Compare commits
221 commits
Author | SHA1 | Date | |
---|---|---|---|
|
b7ca19c331 | ||
|
ca88e55264 | ||
|
b4dda3c180 | ||
|
2c5d113da0 | ||
|
df1a95eeef | ||
|
200b9a75b0 | ||
|
288ea27bc6 | ||
|
d113659ee0 | ||
|
b57f034d01 | ||
|
4f9e97d955 | ||
|
8374f44a53 | ||
|
ac35166073 | ||
|
67f5470d3e | ||
|
0412d2a88a | ||
|
f4833ac94a | ||
|
b3a347c678 | ||
|
ccd95c88ec | ||
|
3f0a3ee063 | ||
|
45dd2754db | ||
|
85a75af9c6 | ||
|
2425e352e8 | ||
|
90ee3ad27c | ||
|
94d58fa8e0 | ||
|
6118f60074 | ||
|
92b4d7d6d9 | ||
|
f5533c92ee | ||
|
dc78a749ab | ||
|
ccd5aafe6b | ||
|
f0d77d7a28 | ||
|
5eb6c089c3 | ||
|
1532fbf949 | ||
|
7e52000c11 | ||
|
e55b8ff264 | ||
|
8ad4f548f7 | ||
|
68ddc9d0f5 | ||
|
392ff1a70a | ||
|
da61043dd9 | ||
|
d60891e201 | ||
|
a193ca9058 | ||
|
89440fa9c7 | ||
|
e348318ce9 | ||
|
20c6157104 | ||
|
a5695dcf3b | ||
|
cdeb806371 | ||
|
a8b8f2e001 | ||
|
d9339e4bfc | ||
|
b02a8c3caf | ||
|
1f0d96b983 | ||
|
b520e30cac | ||
|
bfef100505 | ||
|
c38aecdd3a | ||
|
daa1012e02 | ||
|
b0f594eea1 | ||
|
973b461a54 | ||
|
348067dcfd | ||
|
9b72dd868f | ||
|
93a34cc68d | ||
|
53c643092c | ||
|
a80c85bff8 | ||
|
f5d6b19fb4 | ||
|
196b24c972 | ||
|
7b452c18e0 | ||
|
43ec5d3a07 | ||
|
9b9e0f5b64 | ||
|
d2df889b47 | ||
|
29e78e15ec | ||
|
9457957fe8 | ||
|
2e9fd43095 | ||
|
baf12bbeac | ||
|
9baec5c22f | ||
|
65e81848ba | ||
|
82ac4e0976 | ||
|
9e0d69bbd5 | ||
|
345c0a5269 | ||
|
5ef5444fff | ||
|
d0fd99f75c | ||
|
e6ad70468f | ||
|
7ab4d9ad0b | ||
|
5535aa292f | ||
|
8d1bacf8a6 | ||
|
bf0ad26944 | ||
|
65d377e085 | ||
|
72e9e81d97 | ||
|
c0c4a7bf6b | ||
|
c5fc27920e | ||
|
c646fa686c | ||
|
a4c4c5e542 | ||
|
005959d81c | ||
|
da310a9653 | ||
|
7cbfe62af8 | ||
|
afa34340d8 | ||
|
04755f1a9b | ||
|
349b7e6786 | ||
|
5994eb463a | ||
|
c60f9d1b63 | ||
|
c07f23dc7c | ||
|
bd6445cedc | ||
|
f2c4ec86ea | ||
|
d5c0cfc9e8 | ||
|
668f708308 | ||
|
561fadd4ff | ||
|
7811b779a0 | ||
|
5aaf82b1b5 | ||
|
cca2a33acd | ||
|
8102827215 | ||
|
6f33b8a5f1 | ||
|
33bf3a009d | ||
|
1c1817ddc1 | ||
|
2a3248cfaa | ||
|
b84eb8f2b0 | ||
|
3af34690c0 | ||
|
59f818fe2d | ||
|
fc037cb62b | ||
|
ee2277a610 | ||
|
48127c3754 | ||
|
a25993fc9b | ||
|
c4ff46b243 | ||
|
835e60d900 | ||
|
d416f9fb7b | ||
|
76fe23d3af | ||
|
b16af14611 | ||
|
cd2b13eb57 | ||
|
4122826031 | ||
|
e48aaf5c13 | ||
|
b93d3e5d7e | ||
|
093009137e | ||
|
4b5a73e21b | ||
|
3e866e63b2 | ||
|
e8c029d9da | ||
|
99c67a87cd | ||
|
b6e8d02851 | ||
|
9831e9eb87 | ||
|
a3c4bffd2a | ||
|
57a4040caf | ||
|
049382a961 | ||
|
e52feaa44d | ||
|
68a2ead2fd | ||
|
136e62333e | ||
|
e14fa647a1 | ||
|
9b5f948c7f | ||
|
a9d58ee894 | ||
|
353d082a61 | ||
|
165e05b453 | ||
|
68ab306708 | ||
|
49f5606a67 | ||
|
faaa841272 | ||
|
aa0180b4e8 | ||
|
d08b3d106b | ||
|
e874f9237b | ||
|
493e49257f | ||
|
368ed8b8df | ||
|
2ccda70f76 | ||
|
d6f26742dc | ||
|
85aae33925 | ||
|
4432e93250 | ||
|
7e5337b486 | ||
|
11c6896520 | ||
|
834f354c6b | ||
|
4b22e1075e | ||
|
1b1df8abce | ||
|
fb94665fe3 | ||
|
209af16763 | ||
|
6e5a67c1fb | ||
|
d21d49a8ef | ||
|
4e7175762e | ||
|
1dff366897 | ||
|
6684019e86 | ||
|
c71e7c622d | ||
|
f2d10db402 | ||
|
b05e09700b | ||
|
428641452c | ||
|
b3d7552774 | ||
|
90d5306f09 | ||
|
bcfa73c85d | ||
|
e4a60d7c90 | ||
|
b99cf8a2ca | ||
|
09250ede96 | ||
|
b6cea7c658 | ||
|
f3b6955533 | ||
|
b7a54e5166 | ||
|
3a0cbfd081 | ||
|
f85fe07418 | ||
|
96f7366e9a | ||
|
3f61adc170 | ||
|
da2335328b | ||
|
64f5de14b1 | ||
|
9a109bbf7d | ||
|
04c0bb19a1 | ||
|
4eb26bb452 | ||
|
010714174e | ||
|
164d225f07 | ||
|
9eee695425 | ||
|
2acaa7f9f4 | ||
|
8bf0cff8cb | ||
|
3fc00049f6 | ||
|
8200e1ffc7 | ||
|
dca41aea12 | ||
|
51e2e25f69 | ||
|
4be4260d7e | ||
|
1ce9f76fa3 | ||
|
fd257f85aa | ||
|
80fd4a96aa | ||
|
6dfd4f92c6 | ||
|
1cbfbbcc1a | ||
|
dea5dd5d82 | ||
|
a55ff6b33e | ||
|
2a330740cf | ||
|
51920be9a7 | ||
|
8fbcf58e98 | ||
|
e7e25bb122 | ||
|
492e39d9ad | ||
|
95c9d89afe | ||
|
dfe41c4930 | ||
|
6acd0b05ab | ||
|
6d4abf908d | ||
|
009ad3b5e7 | ||
|
fc50e6b19a | ||
|
07ed49c1a0 | ||
|
d2bb56a71f | ||
|
3606751565 | ||
|
79bdcf3718 |
92 changed files with 3367 additions and 2859 deletions
9
Makefile
9
Makefile
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
OS := $(shell uname -s)
|
OS := $(shell uname -s)
|
||||||
|
|
||||||
PYTHON = python
|
PYTHON = python
|
||||||
|
@ -50,10 +49,10 @@ src/json/libmapnik-json.a:
|
||||||
src/renderer_common/render_thunk_extractor.os \
|
src/renderer_common/render_thunk_extractor.os \
|
||||||
src/json/libmapnik-json.a \
|
src/json/libmapnik-json.a \
|
||||||
src/wkt/libmapnik-wkt.a \
|
src/wkt/libmapnik-wkt.a \
|
||||||
src/css_color_grammar.os \
|
src/css_color_grammar_x3.os \
|
||||||
src/expression_grammar.os \
|
src/expression_grammar_x3.os \
|
||||||
src/transform_expression_grammar.os \
|
src/transform_expression_grammar_x3.os \
|
||||||
src/image_filter_grammar.os \
|
src/image_filter_grammar_x3.os \
|
||||||
src/marker_helpers.os \
|
src/marker_helpers.os \
|
||||||
src/svg/svg_transform_parser.os \
|
src/svg/svg_transform_parser.os \
|
||||||
src/agg/process_line_symbolizer.os \
|
src/agg/process_line_symbolizer.os \
|
||||||
|
|
|
@ -41,7 +41,7 @@ ICU_LIBS_DEFAULT='/usr/'
|
||||||
|
|
||||||
DEFAULT_CC = "cc"
|
DEFAULT_CC = "cc"
|
||||||
DEFAULT_CXX = "c++"
|
DEFAULT_CXX = "c++"
|
||||||
DEFAULT_CXX11_CXXFLAGS = " -std=c++11"
|
DEFAULT_CXX11_CXXFLAGS = " -std=c++14"
|
||||||
DEFAULT_CXX11_LINKFLAGS = ""
|
DEFAULT_CXX11_LINKFLAGS = ""
|
||||||
if sys.platform == 'darwin':
|
if sys.platform == 'darwin':
|
||||||
# homebrew default
|
# 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)
|
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']:
|
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']:
|
if env['DEBUG']:
|
||||||
env.Append(CXXFLAGS = common_cxx_flags + '-O0')
|
env.Append(CXXFLAGS = common_cxx_flags + '-O0')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -24,7 +24,7 @@ run test_getline 30 10000000
|
||||||
#run test_polygon_clipping 10 1000
|
#run test_polygon_clipping 10 1000
|
||||||
#run test_polygon_clipping_rendering 10 100
|
#run test_polygon_clipping_rendering 10 100
|
||||||
run test_proj_transform1 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_face_ptr_creation 10 1000
|
||||||
run test_font_registration 10 100
|
run test_font_registration 10 100
|
||||||
run test_offset_converter 10 1000
|
run test_offset_converter 10 1000
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
#include "bench_framework.hpp"
|
#include "bench_framework.hpp"
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <mapnik/attribute.hpp>
|
||||||
#include <mapnik/expression.hpp>
|
#include <mapnik/expression.hpp>
|
||||||
#include <mapnik/expression_string.hpp>
|
#include <mapnik/expression_string.hpp>
|
||||||
#include <mapnik/expression_grammar.hpp>
|
|
||||||
|
|
||||||
class test : public benchmark::test_case
|
class test : public benchmark::test_case
|
||||||
{
|
{
|
||||||
|
|
10
deps/agg/include/agg_vpgen_clip_polygon.h
vendored
10
deps/agg/include/agg_vpgen_clip_polygon.h
vendored
|
@ -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.x1 = _x1;
|
||||||
m_clip_box.y1 = y1;
|
m_clip_box.y1 = _y1;
|
||||||
m_clip_box.x2 = x2;
|
m_clip_box.x2 = _x2;
|
||||||
m_clip_box.y2 = y2;
|
m_clip_box.y2 = _y2;
|
||||||
m_clip_box.normalize();
|
m_clip_box.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
deps/agg/include/agg_vpgen_clip_polyline.h
vendored
10
deps/agg/include/agg_vpgen_clip_polyline.h
vendored
|
@ -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.x1 = _x1;
|
||||||
m_clip_box.y1 = y1;
|
m_clip_box.y1 = _y1;
|
||||||
m_clip_box.x2 = x2;
|
m_clip_box.x2 = _x2;
|
||||||
m_clip_box.y2 = y2;
|
m_clip_box.y2 = _y2;
|
||||||
m_clip_box.normalize();
|
m_clip_box.normalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,11 @@ template <typename T> class MAPNIK_DECL box2d
|
||||||
public:
|
public:
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
using box2d_type = box2d<value_type>;
|
using box2d_type = box2d<value_type>;
|
||||||
private:
|
|
||||||
T minx_;
|
T minx_;
|
||||||
T miny_;
|
T miny_;
|
||||||
T maxx_;
|
T maxx_;
|
||||||
T maxy_;
|
T maxy_;
|
||||||
|
private:
|
||||||
friend inline void swap(box2d_type & lhs, box2d_type & rhs)
|
friend inline void swap(box2d_type & lhs, box2d_type & rhs)
|
||||||
{
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
|
|
|
@ -33,24 +33,35 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/fusion/include/adapt_adt.hpp>
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/spirit/include/support_adapt_adt_attributes.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// agg
|
// agg
|
||||||
#include "agg_trans_affine.h"
|
#include "agg_trans_affine.h"
|
||||||
|
|
||||||
BOOST_FUSION_ADAPT_TPL_ADT(
|
BOOST_FUSION_ADAPT_TPL_STRUCT(
|
||||||
(T),
|
(T),
|
||||||
(mapnik::box2d)(T),
|
(mapnik::box2d)(T),
|
||||||
(T, T, obj.minx(), obj.set_minx(mapnik::safe_cast<T>(val)))
|
(T, minx_),
|
||||||
(T, T, obj.miny(), obj.set_miny(mapnik::safe_cast<T>(val)))
|
(T, miny_),
|
||||||
(T, T, obj.maxx(), obj.set_maxx(mapnik::safe_cast<T>(val)))
|
(T, maxx_),
|
||||||
(T, T, obj.maxy(), obj.set_maxy(mapnik::safe_cast<T>(val))))
|
(T, maxy_))
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik { namespace detail { namespace {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct assign
|
||||||
{
|
{
|
||||||
|
template <typename Context>
|
||||||
|
void operator() (Context & ctx) const
|
||||||
|
{
|
||||||
|
_val(ctx) = safe_cast<T>(_attr(ctx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // anonymous
|
||||||
|
} // detail
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
box2d<T>::box2d()
|
box2d<T>::box2d()
|
||||||
:minx_( std::numeric_limits<T>::max()),
|
:minx_( std::numeric_limits<T>::max()),
|
||||||
|
@ -350,12 +361,15 @@ void box2d<T>::pad(T padding)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool box2d<T>::from_string(std::string const& str)
|
bool box2d<T>::from_string(std::string const& str)
|
||||||
{
|
{
|
||||||
boost::spirit::qi::lit_type lit;
|
using boost::spirit::x3::lit;
|
||||||
boost::spirit::qi::double_type double_;
|
boost::spirit::x3::double_type double_;
|
||||||
boost::spirit::ascii::space_type space;
|
boost::spirit::x3::ascii::space_type space;
|
||||||
bool r = boost::spirit::qi::phrase_parse(str.begin(),
|
bool r = boost::spirit::x3::phrase_parse(str.begin(),
|
||||||
str.end(),
|
str.end(),
|
||||||
double_ >> -lit(',') >> double_ >> -lit(',') >> double_ >> -lit(',') >> double_,
|
double_[detail::assign<T>()] >> -lit(',') >>
|
||||||
|
double_[detail::assign<T>()] >> -lit(',') >>
|
||||||
|
double_[detail::assign<T>()] >> -lit(',') >>
|
||||||
|
double_[detail::assign<T>()],
|
||||||
space,
|
space,
|
||||||
*this);
|
*this);
|
||||||
return r;
|
return r;
|
||||||
|
|
|
@ -38,16 +38,15 @@
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
class MAPNIK_DECL color
|
class MAPNIK_DECL color : boost::equality_comparable<color>
|
||||||
: boost::equality_comparable<color>
|
|
||||||
{
|
{
|
||||||
private:
|
public:
|
||||||
std::uint8_t red_;
|
std::uint8_t red_;
|
||||||
std::uint8_t green_;
|
std::uint8_t green_;
|
||||||
std::uint8_t blue_;
|
std::uint8_t blue_;
|
||||||
std::uint8_t alpha_;
|
std::uint8_t alpha_;
|
||||||
bool premultiplied_;
|
bool premultiplied_;
|
||||||
public:
|
|
||||||
// default ctor
|
// default ctor
|
||||||
color()
|
color()
|
||||||
: red_(0xff),
|
: red_(0xff),
|
||||||
|
|
|
@ -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 <mapnik/color.hpp>
|
|
||||||
#include <mapnik/util/hsl.hpp>
|
|
||||||
#include <mapnik/safe_cast.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
namespace ascii = boost::spirit::ascii;
|
|
||||||
|
|
||||||
using ascii_space_type = boost::spirit::ascii::space_type;
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
struct css_color_grammar : qi::grammar<Iterator, color(), ascii_space_type>
|
|
||||||
{
|
|
||||||
// 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<Iterator, color(), ascii_space_type> rgba_color;
|
|
||||||
qi::rule<Iterator, color(), ascii_space_type> rgba_percent_color;
|
|
||||||
qi::rule<Iterator, qi::locals<double,double,double>,color(), ascii_space_type> hsl_percent_color;
|
|
||||||
qi::rule<Iterator, color(), ascii_space_type> hex_color;
|
|
||||||
qi::rule<Iterator, color(), ascii_space_type> hex_color_small;
|
|
||||||
qi::rule<Iterator, color(), ascii_space_type> css_color;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // MAPNIK_CSS_COLOR_GRAMMAR_HPP
|
|
55
include/mapnik/css_color_grammar_x3.hpp
Normal file
55
include/mapnik/css_color_grammar_x3.hpp
Normal file
|
@ -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 <mapnik/color.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#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<css_color_class, mapnik::color>;
|
||||||
|
|
||||||
|
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
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
// REF: http://www.w3.org/TR/css3-color/
|
||||||
// from implementation files. It therefore doesn't have an include guard.
|
|
||||||
// mapnik
|
#ifndef MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
||||||
#include <mapnik/css_color_grammar.hpp>
|
#define MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
||||||
// boost
|
|
||||||
|
#include <mapnik/css_color_grammar_x3.hpp>
|
||||||
|
#include <mapnik/util/hsl.hpp>
|
||||||
|
#include <mapnik/safe_cast.hpp>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <boost/fusion/include/adapt_adt.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
#include <boost/fusion/adapted/struct.hpp>
|
||||||
#include <boost/spirit/include/phoenix_fusion.hpp>
|
#include <boost/fusion/adapted/std_tuple.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
BOOST_FUSION_ADAPT_STRUCT (
|
||||||
BOOST_FUSION_ADAPT_ADT(
|
|
||||||
mapnik::color,
|
mapnik::color,
|
||||||
(unsigned, unsigned, obj.red(), obj.set_red(mapnik::safe_cast<uint8_t>(val)))
|
(std::uint8_t, red_)
|
||||||
(unsigned, unsigned, obj.green(), obj.set_green(mapnik::safe_cast<uint8_t>(val)))
|
(std::uint8_t, green_)
|
||||||
(unsigned, unsigned, obj.blue(), obj.set_blue(mapnik::safe_cast<uint8_t>(val)))
|
(std::uint8_t, blue_)
|
||||||
(unsigned, unsigned, obj.alpha(), obj.set_alpha(mapnik::safe_cast<uint8_t>(val)))
|
(std::uint8_t, alpha_)
|
||||||
)
|
)
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik {
|
||||||
{
|
|
||||||
namespace phoenix = boost::phoenix;
|
|
||||||
|
|
||||||
struct percent_conv_impl
|
namespace x3 = boost::spirit::x3;
|
||||||
{
|
|
||||||
using result_type = unsigned;
|
|
||||||
unsigned operator() (double val) const
|
|
||||||
{
|
|
||||||
return safe_cast<uint8_t>(std::lround((255.0 * val)/100.0));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct alpha_conv_impl
|
namespace css_color_grammar {
|
||||||
{
|
|
||||||
using result_type = unsigned;
|
|
||||||
unsigned operator() (double val) const
|
|
||||||
{
|
|
||||||
return safe_cast<uint8_t>(std::lround((255.0 * val)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct hsl_conv_impl
|
using x3::lit;
|
||||||
{
|
using x3::uint_parser;
|
||||||
using result_type = void;
|
using x3::hex;
|
||||||
template <typename T0,typename T1, typename T2, typename T3>
|
using x3::symbols;
|
||||||
void operator() (T0 & c, T1 h, T2 s, T3 l) const
|
using x3::omit;
|
||||||
{
|
using x3::attr;
|
||||||
double m1,m2;
|
using x3::double_;
|
||||||
// normalize values
|
using x3::no_case;
|
||||||
h /= 360.0;
|
using x3::no_skip;
|
||||||
s /= 100.0;
|
|
||||||
l /= 100.0;
|
|
||||||
|
|
||||||
if (l <= 0.5)
|
struct named_colors_ : x3::symbols<color>
|
||||||
{
|
{
|
||||||
m2 = l * (s + 1.0);
|
named_colors_()
|
||||||
}
|
|
||||||
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<uint8_t>(std::lround(255.0 * r)));
|
|
||||||
c.set_green(safe_cast<uint8_t>(std::lround(255.0 * g)));
|
|
||||||
c.set_blue(safe_cast<uint8_t>(std::lround(255.0 * b)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct named_colors : qi::symbols<char,color>
|
|
||||||
{
|
|
||||||
named_colors()
|
|
||||||
{
|
{
|
||||||
add
|
add
|
||||||
("aliceblue", color(240, 248, 255))
|
("aliceblue", color(240, 248, 255))
|
||||||
|
@ -249,77 +214,241 @@ struct named_colors : qi::symbols<char,color>
|
||||||
("transparent", color(0, 0, 0, 0))
|
("transparent", color(0, 0, 0, 0))
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
} named_colors;
|
||||||
|
|
||||||
|
x3::uint_parser<std::uint8_t, 16, 2, 2> hex2;
|
||||||
|
x3::uint_parser<std::uint8_t, 16, 1, 1> hex1;
|
||||||
|
x3::uint_parser<std::uint8_t, 10, 1, 3> dec3;
|
||||||
|
|
||||||
|
// starting rule
|
||||||
|
css_color_grammar_type const css_color("css_color");
|
||||||
|
// rules
|
||||||
|
x3::rule<class hex2_color, color> const hex2_color("hex2_color");
|
||||||
|
x3::rule<class hex1_color, color> const hex1_color("hex1_color");
|
||||||
|
x3::rule<class rgb_color, color> const rgb_color("rgb_color");
|
||||||
|
x3::rule<class rgba_color, color> const rgba_color("rgba_color");
|
||||||
|
x3::rule<class rgb_color_percent, color> const rgb_color_percent("rgb_color_percent");
|
||||||
|
x3::rule<class rgba_color_percent, color> 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 <typename Iterator>
|
struct percent_converter
|
||||||
css_color_grammar<Iterator>::css_color_grammar()
|
|
||||||
: css_color_grammar::base_type(css_color)
|
|
||||||
|
|
||||||
{
|
{
|
||||||
qi::lit_type lit;
|
static std::uint8_t call(double val)
|
||||||
qi::_val_type _val;
|
{
|
||||||
qi::double_type double_;
|
return safe_cast<std::uint8_t>(std::lround((255.0 * val)/100.0));
|
||||||
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_conv_impl> percent_converter;
|
|
||||||
phoenix::function<alpha_conv_impl> alpha_converter;
|
|
||||||
phoenix::function<hsl_conv_impl> hsl_converter;
|
|
||||||
|
|
||||||
css_color %= rgba_color
|
auto dec_red = [](auto& ctx)
|
||||||
| rgba_percent_color
|
{
|
||||||
| hsl_percent_color
|
_val(ctx).red_ = _attr(ctx);
|
||||||
| hex_color
|
};
|
||||||
| hex_color_small
|
|
||||||
| no_case[named];
|
|
||||||
|
|
||||||
hex_color = lexeme[ lit('#')
|
auto dec_green = [](auto& ctx)
|
||||||
>> hex2 [ at_c<0>(_val) = _1 ]
|
{
|
||||||
>> hex2 [ at_c<1>(_val) = _1 ]
|
_val(ctx).green_ = _attr(ctx);
|
||||||
>> hex2 [ at_c<2>(_val) = _1 ]
|
};
|
||||||
>>-hex2 [ at_c<3>(_val) = _1 ] ]
|
|
||||||
|
auto dec_blue = [](auto& ctx)
|
||||||
|
{
|
||||||
|
_val(ctx).blue_ = _attr(ctx);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto opacity = [](auto& ctx)
|
||||||
|
{
|
||||||
|
_val(ctx).alpha_ = uint8_t((255.0 * clip_opacity::call(_attr(ctx))) + 0.5);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto percent_red = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx).red_ = percent_converter::call(_attr(ctx));
|
||||||
|
};
|
||||||
|
|
||||||
|
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<uint8_t>(std::lround(255.0 * r)),
|
||||||
|
safe_cast<uint8_t>(std::lround(255.0 * g)),
|
||||||
|
safe_cast<uint8_t>(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<class hsl_values, std::tuple<std::uint8_t,std::uint8_t,std::uint8_t, double >> {} =
|
||||||
|
lit("hsl")
|
||||||
|
>> lit('(') >> dec3
|
||||||
|
>> lit(',') >> dec3 >> lit('%')
|
||||||
|
>> lit(',') >> dec3 >> lit('%')
|
||||||
|
>> attr(1.0) >> lit(')')
|
||||||
;
|
;
|
||||||
|
|
||||||
hex_color_small = lexeme[ lit('#')
|
auto const hsla_values = x3::rule<class hsla_values, std::tuple<std::uint8_t,std::uint8_t,std::uint8_t, double >> {} =
|
||||||
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
|
lit("hsla")
|
||||||
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
|
>> lit('(') >> dec3
|
||||||
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
|
>> lit(',') >> dec3 >> lit('%')
|
||||||
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] ]
|
>> lit(',') >> dec3 >> lit('%')
|
||||||
|
>> lit(',') >> double_ >> lit(')')
|
||||||
;
|
;
|
||||||
|
|
||||||
rgba_color = lit("rgb") >> -lit('a')
|
auto const hsl_color = x3::rule<class hsl_color, color> {} = hsl_values[hsl_to_rgba];
|
||||||
>> lit('(')
|
auto const hsla_color = x3::rule<class hsla_color, color> {} = hsla_values[hsl_to_rgba];
|
||||||
>> dec3 [at_c<0>(_val) = _1] >> ','
|
|
||||||
>> dec3 [at_c<1>(_val) = _1] >> ','
|
auto const css_color_def =
|
||||||
>> dec3 [at_c<2>(_val) = _1]
|
no_case[named_colors]
|
||||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
|
|
||||||
>> lit(')')
|
hex2_color
|
||||||
|
|
|
||||||
|
hex1_color
|
||||||
|
|
|
||||||
|
rgb_color
|
||||||
|
|
|
||||||
|
rgba_color
|
||||||
|
|
|
||||||
|
rgb_color_percent
|
||||||
|
|
|
||||||
|
rgba_color_percent
|
||||||
|
|
|
||||||
|
hsl_color
|
||||||
|
|
|
||||||
|
hsla_color
|
||||||
;
|
;
|
||||||
|
|
||||||
rgba_percent_color = lit("rgb") >> -lit('a')
|
#pragma GCC diagnostic push
|
||||||
>> lit('(')
|
#include <mapnik/warning_ignore.hpp>
|
||||||
>> double_ [at_c<0>(_val) = percent_converter(_1)] >> '%' >> ','
|
BOOST_SPIRIT_DEFINE(
|
||||||
>> double_ [at_c<1>(_val) = percent_converter(_1)] >> '%' >> ','
|
css_color,
|
||||||
>> double_ [at_c<2>(_val) = percent_converter(_1)] >> '%'
|
hex2_color,
|
||||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)])
|
hex1_color,
|
||||||
>> lit(')')
|
rgb_color,
|
||||||
;
|
rgba_color,
|
||||||
|
rgb_color_percent,
|
||||||
|
rgba_color_percent
|
||||||
|
);
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
hsl_percent_color = lit("hsl") >> -lit('a')
|
} // ns
|
||||||
>> lit('(')
|
|
||||||
>> double_ [ _a = _1] >> ',' // hue 0..360
|
css_color_grammar::css_color_grammar_type color_grammar()
|
||||||
>> double_ [ _b = _1] >> '%' >> ',' // saturation 0..100%
|
{
|
||||||
>> double_ [ _c = _1] >> '%' // lightness 0..100%
|
return css_color_grammar::css_color;
|
||||||
>> -(','>> -double_ [at_c<3>(_val) = alpha_converter(_1)]) // opacity 0...1
|
|
||||||
>> lit (')') [ hsl_converter(_val,_a,_b,_c)]
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} //ns mapnik
|
||||||
|
|
||||||
|
#endif //MAPNIK_CSS_COLOR_GRAMMAR_X3_DEF_HPP
|
|
@ -69,8 +69,8 @@ public:
|
||||||
Raster
|
Raster
|
||||||
};
|
};
|
||||||
|
|
||||||
datasource (parameters const& params)
|
datasource (parameters const& _params)
|
||||||
: params_(params) {}
|
: params_(_params) {}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Get the configuration parameters of the data source.
|
* @brief Get the configuration parameters of the data source.
|
||||||
|
|
|
@ -43,8 +43,8 @@ struct evaluate_expression
|
||||||
{
|
{
|
||||||
using value_type = T;
|
using value_type = T;
|
||||||
|
|
||||||
explicit evaluate_expression(Attributes const& attributes)
|
explicit evaluate_expression(Attributes const& _attributes)
|
||||||
: attributes_(attributes) {}
|
: attributes_(_attributes) {}
|
||||||
|
|
||||||
value_type operator() (attribute const&) const
|
value_type operator() (attribute const&) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -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 <mapnik/config.hpp>
|
|
||||||
#include <mapnik/expression_node.hpp>
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
namespace standard_wide = boost::spirit::standard_wide;
|
|
||||||
using standard_wide::space_type;
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct integer_parser
|
|
||||||
{
|
|
||||||
using type = qi::int_parser<T,10,1,-1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct unary_function_types : qi::symbols<char, unary_function_impl>
|
|
||||||
{
|
|
||||||
unary_function_types();
|
|
||||||
};
|
|
||||||
|
|
||||||
struct binary_function_types : qi::symbols<char, binary_function_impl>
|
|
||||||
{
|
|
||||||
binary_function_types();
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __GNUC__
|
|
||||||
template <typename Iterator>
|
|
||||||
struct MAPNIK_DECL expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|
||||||
#else
|
|
||||||
template <typename Iterator>
|
|
||||||
struct expression_grammar : qi::grammar<Iterator, expr_node(), space_type>
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
using rule_type = qi::rule<Iterator, expr_node(), space_type>;
|
|
||||||
|
|
||||||
explicit expression_grammar(std::string const& encoding = "utf-8");
|
|
||||||
|
|
||||||
qi::real_parser<double, qi::strict_real_policies<double> > strict_double;
|
|
||||||
typename integer_parser<mapnik::value_integer>::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<Iterator, unary_function_call() , space_type> unary_function_expr;
|
|
||||||
qi::rule<Iterator, binary_function_call() , space_type> binary_function_expr;
|
|
||||||
qi::rule<Iterator, std::string() > regex_match_expr;
|
|
||||||
qi::rule<Iterator, expr_node(expr_node), qi::locals<std::string,std::string>, space_type> regex_replace_expr;
|
|
||||||
qi::rule<Iterator, std::string() , space_type> attr;
|
|
||||||
qi::rule<Iterator, std::string() , space_type> global_attr;
|
|
||||||
qi::rule<Iterator, std::string(), qi::locals<char> > quoted_ustring;
|
|
||||||
qi::rule<Iterator, std::string()> unquoted_ustring;
|
|
||||||
qi::rule<Iterator, std::string(), space_type> ustring;
|
|
||||||
|
|
||||||
qi::symbols<char const, char const> unesc_char;
|
|
||||||
qi::rule<Iterator, char() > quote_char;
|
|
||||||
qi::symbols<char, expr_node> constant;
|
|
||||||
unary_function_types unary_func_type;
|
|
||||||
binary_function_types binary_func_type;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_HPP
|
|
|
@ -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 <mapnik/expression_node.hpp>
|
|
||||||
#include <mapnik/expression_grammar.hpp>
|
|
||||||
#include <mapnik/unicode.hpp>
|
|
||||||
#include <mapnik/value_types.hpp>
|
|
||||||
#include <mapnik/function_call.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/fusion/adapted/struct.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_object.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_function.hpp>
|
|
||||||
#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 <typename T0,typename T1>
|
|
||||||
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 <typename T0,typename T1,typename T2>
|
|
||||||
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 <typename T0,typename T1>
|
|
||||||
expr_node regex_match_impl::operator() (T0 & node, T1 const& pattern) const
|
|
||||||
{
|
|
||||||
return regex_match_node(tr_,node,pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T0,typename T1,typename T2>
|
|
||||||
expr_node regex_replace_impl::operator() (T0 & node, T1 const& pattern, T2 const& format) const
|
|
||||||
{
|
|
||||||
return regex_replace_node(tr_,node,pattern,format);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
expression_grammar<Iterator>::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_impl> unicode = unicode_impl(tr_);
|
|
||||||
boost::phoenix::function<regex_match_impl> regex_match = regex_match_impl(tr_);
|
|
||||||
boost::phoenix::function<regex_replace_impl> 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<mapnik::expr_node>(_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<mapnik::geometry_type_attribute>(),
|
|
||||||
_val = construct<mapnik::attribute>(_1))]
|
|
||||||
| global_attr [_val = construct<mapnik::global_attribute>( _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_('-'))];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
51
include/mapnik/expression_grammar_x3.hpp
Normal file
51
include/mapnik/expression_grammar_x3.hpp
Normal file
|
@ -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 <mapnik/expression_node.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#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<expression_class, expr_node>;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_DECLARE(expression_grammar_type);
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
namespace mapnik
|
||||||
|
{
|
||||||
|
grammar::expression_grammar_type expression_grammar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_HPP
|
43
include/mapnik/expression_grammar_x3_config.hpp
Normal file
43
include/mapnik/expression_grammar_x3_config.hpp
Normal file
|
@ -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 <mapnik/expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
|
namespace x3 = boost::spirit::x3;
|
||||||
|
using iterator_type = std::string::const_iterator;
|
||||||
|
using phrase_context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
|
||||||
|
|
||||||
|
// define combined context
|
||||||
|
using context_type = x3::with_context<transcoder_tag,
|
||||||
|
std::reference_wrapper<mapnik::transcoder const> const,
|
||||||
|
phrase_context_type>::type;
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // MAPNIK_EXPRESSIONS_GRAMMAR_X3_CONFIG_HPP
|
433
include/mapnik/expression_grammar_x3_def.hpp
Normal file
433
include/mapnik/expression_grammar_x3_def.hpp
Normal file
|
@ -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 <mapnik/expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/expression_node.hpp>
|
||||||
|
#include <mapnik/function_call.hpp>
|
||||||
|
#include <mapnik/unicode.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#include <boost/spirit/home/x3/support/ast/variant.hpp>
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
|
#include <boost/fusion/include/std_pair.hpp>
|
||||||
|
#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<mapnik::tags::negate>(_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<mapnik::tags::plus>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_subt = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::minus>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_mult = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::mult>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_div = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::div>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_mod = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::mod>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_unicode = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
auto & tr = x3::get<transcoder_tag>(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<mapnik::tags::logical_not> node(_attr(ctx));
|
||||||
|
_val(ctx) = std::move(node);
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_and = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::logical_and>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_or = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::logical_or>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_equal = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::equal_to>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_not_equal = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::not_equal_to>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_less = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::less>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_less_equal = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::less_equal>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_greater = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::greater>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
auto do_greater_equal = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
_val(ctx) = std::move(mapnik::binary_node<mapnik::tags::greater_equal>(std::move(_val(ctx)), std::move(_attr(ctx))));
|
||||||
|
};
|
||||||
|
|
||||||
|
// regex
|
||||||
|
auto do_regex_match = [] (auto & ctx)
|
||||||
|
{
|
||||||
|
auto const& tr = x3::get<transcoder_tag>(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<transcoder_tag>(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<value_integer,10,1,-1>();
|
||||||
|
// mapnik::value_double
|
||||||
|
auto const mapnik_double = x3::real_parser<value_double, x3::strict_real_policies<value_double>>();
|
||||||
|
// mapnik::value_bool
|
||||||
|
struct boolean_ : x3::symbols<mapnik::value_bool>
|
||||||
|
{
|
||||||
|
boolean_()
|
||||||
|
{
|
||||||
|
add
|
||||||
|
("true", true)
|
||||||
|
("false", false)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} boolean;
|
||||||
|
|
||||||
|
struct floating_point_constants : x3::symbols<mapnik::value_double>
|
||||||
|
{
|
||||||
|
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_impl>
|
||||||
|
{
|
||||||
|
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_impl>
|
||||||
|
{
|
||||||
|
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<mapnik::value_integer>
|
||||||
|
{
|
||||||
|
geometry_types_()
|
||||||
|
{
|
||||||
|
add
|
||||||
|
("point", 1)
|
||||||
|
("linestring", 2)
|
||||||
|
("polygon",3)
|
||||||
|
("collection",4)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
} geometry_type;
|
||||||
|
|
||||||
|
struct unesc_chars_ : x3::symbols<char>
|
||||||
|
{
|
||||||
|
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<class logical_expression, mapnik::expr_node> const logical_expression("logical expression");
|
||||||
|
x3::rule<class not_expression, mapnik::expr_node> const not_expression("not expression");
|
||||||
|
x3::rule<class conditional_expression, mapnik::expr_node> const conditional_expression("conditional expression");
|
||||||
|
x3::rule<class equality_expression, mapnik::expr_node> const equality_expression("equality expression");
|
||||||
|
x3::rule<class relational_expression, mapnik::expr_node> const relational_expression("relational expression");
|
||||||
|
x3::rule<class additive_expression, mapnik::expr_node> const additive_expression("additive expression");
|
||||||
|
x3::rule<class multiplicative_expression, mapnik::expr_node> const multiplicative_expression("multiplicative expression");
|
||||||
|
x3::rule<class unary_func_expression, mapnik::unary_function_call> const unary_func_expression("unary function expression");
|
||||||
|
x3::rule<class binary_func_expression, mapnik::binary_function_call> const binary_func_expression("binary function expression");
|
||||||
|
x3::rule<class unary_expression, mapnik::expr_node> const unary_expression("unary expression");
|
||||||
|
x3::rule<class primary_expression, mapnik::expr_node> const primary_expression("primary expression");
|
||||||
|
x3::rule<class regex_match_expression, std::string> const regex_match_expression("regex match expression");
|
||||||
|
x3::rule<class regex_replace_expression, std::pair<std::string,std::string> > const regex_replace_expression("regex replace expression");
|
||||||
|
|
||||||
|
// strings
|
||||||
|
auto const single_quoted_string = x3::rule<class single_quoted_string, std::string> {} = lit('\'') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '\''))] > '\'';
|
||||||
|
auto const double_quoted_string = x3::rule<class double_quoted_string, std::string> {} = lit('"') >> no_skip[*(unesc_char | ("\\x" > hex) | (char_ - '"'))] > '"';
|
||||||
|
auto const quoted_string = x3::rule<class quoted_string, std::string> {} = single_quoted_string | double_quoted_string;
|
||||||
|
|
||||||
|
auto const unquoted_ustring = x3::rule<class ustring, std::string> {} = 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<class global_attr, std::string> {} = 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
|
|
@ -59,7 +59,10 @@ template <> struct make_op<mapnik::tags::logical_or> { using type = std::logica
|
||||||
template <typename Tag>
|
template <typename Tag>
|
||||||
struct unary_node
|
struct unary_node
|
||||||
{
|
{
|
||||||
unary_node (expr_node const& a)
|
unary_node (expr_node && a)
|
||||||
|
: expr(std::move(a)) {}
|
||||||
|
|
||||||
|
unary_node (expr_node const a)
|
||||||
: expr(a) {}
|
: expr(a) {}
|
||||||
|
|
||||||
static const char* type()
|
static const char* type()
|
||||||
|
@ -73,6 +76,10 @@ struct unary_node
|
||||||
template <typename Tag>
|
template <typename Tag>
|
||||||
struct binary_node
|
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)
|
binary_node(expr_node const& a, expr_node const& b)
|
||||||
: left(a),
|
: left(a),
|
||||||
right(b) {}
|
right(b) {}
|
||||||
|
@ -130,81 +137,6 @@ struct MAPNIK_DECL regex_replace_node
|
||||||
std::shared_ptr<_regex_replace_impl> impl_;
|
std::shared_ptr<_regex_replace_impl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline expr_node & operator- (expr_node& expr)
|
|
||||||
{
|
|
||||||
return expr = unary_node<mapnik::tags::negate>(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator += ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::plus>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator -= ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::minus>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator *= ( expr_node &left , expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::mult>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator /= ( expr_node &left , expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::div>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator %= ( expr_node &left , expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::mod>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator < ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::less>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator <= ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::less_equal>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator > ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::greater>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator >= ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::greater_equal>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator == ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::equal_to>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator != ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::not_equal_to>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator ! (expr_node & expr)
|
|
||||||
{
|
|
||||||
return expr = unary_node<mapnik::tags::logical_not>(expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator && ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::logical_and>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline expr_node & operator || ( expr_node &left, expr_node const& right)
|
|
||||||
{
|
|
||||||
return left = binary_node<mapnik::tags::logical_or>(left,right);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -367,10 +367,10 @@ void feature_style_processor<Processor>::prepare_layer(layer_rendering_material
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<rule> const& rules = style->get_rules();
|
std::vector<rule> const& style_rules = style->get_rules();
|
||||||
bool active_rules = false;
|
bool active_rules = false;
|
||||||
rule_cache rc;
|
rule_cache rc;
|
||||||
for(rule const& r : rules)
|
for(rule const& r : style_rules)
|
||||||
{
|
{
|
||||||
if (r.active(scale_denom))
|
if (r.active(scale_denom))
|
||||||
{
|
{
|
||||||
|
|
|
@ -47,7 +47,6 @@ struct exp_impl
|
||||||
{
|
{
|
||||||
return std::exp(val.to_double());
|
return std::exp(val.to_double());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// log
|
// log
|
||||||
|
@ -58,7 +57,6 @@ struct log_impl
|
||||||
{
|
{
|
||||||
return std::log(val.to_double());
|
return std::log(val.to_double());
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// sin
|
// sin
|
||||||
|
@ -102,7 +100,7 @@ struct abs_impl
|
||||||
{
|
{
|
||||||
value_type operator() (value_type const& val) const
|
value_type operator() (value_type const& val) const
|
||||||
{
|
{
|
||||||
return std::fabs(val.to_double());
|
return std::abs(val.to_double());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -124,9 +124,9 @@ public:
|
||||||
return pixmap_.painted();
|
return pixmap_.painted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void painted(bool painted)
|
void painted(bool _painted)
|
||||||
{
|
{
|
||||||
pixmap_.painted(painted);
|
pixmap_.painted(_painted);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
|
|
||||||
hit_grid_view(unsigned x, unsigned y,
|
hit_grid_view(unsigned x, unsigned y,
|
||||||
unsigned width, unsigned height,
|
unsigned width, unsigned height,
|
||||||
T const& data,
|
T const& _data,
|
||||||
std::string const& key,
|
std::string const& key,
|
||||||
std::string const& id_name,
|
std::string const& id_name,
|
||||||
std::set<std::string> const& names,
|
std::set<std::string> const& names,
|
||||||
|
@ -63,7 +63,7 @@ public:
|
||||||
y_(y),
|
y_(y),
|
||||||
width_(width),
|
width_(width),
|
||||||
height_(height),
|
height_(height),
|
||||||
data_(data),
|
data_(_data),
|
||||||
key_(key),
|
key_(key),
|
||||||
id_name_(id_name),
|
id_name_(id_name),
|
||||||
names_(names),
|
names_(names),
|
||||||
|
|
|
@ -681,7 +681,7 @@ void apply_filter(Src & src, scale_hsla const& transform)
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Src, typename ColorBlindFilter>
|
template <typename Src, typename ColorBlindFilter>
|
||||||
void color_blind_filter(Src & src, ColorBlindFilter const& op)
|
void apply_color_blind_filter(Src & src, ColorBlindFilter const& op)
|
||||||
{
|
{
|
||||||
using namespace boost::gil;
|
using namespace boost::gil;
|
||||||
rgba8_view_t src_view = rgba8_view(src);
|
rgba8_view_t src_view = rgba8_view(src);
|
||||||
|
@ -804,19 +804,19 @@ void color_blind_filter(Src & src, ColorBlindFilter const& op)
|
||||||
template <typename Src>
|
template <typename Src>
|
||||||
void apply_filter(Src & src, color_blind_protanope const& op)
|
void apply_filter(Src & src, color_blind_protanope const& op)
|
||||||
{
|
{
|
||||||
color_blind_filter(src, op);
|
apply_color_blind_filter(src, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Src>
|
template <typename Src>
|
||||||
void apply_filter(Src & src, color_blind_deuteranope const& op)
|
void apply_filter(Src & src, color_blind_deuteranope const& op)
|
||||||
{
|
{
|
||||||
color_blind_filter(src, op);
|
apply_color_blind_filter(src, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Src>
|
template <typename Src>
|
||||||
void apply_filter(Src & src, color_blind_tritanope const& op)
|
void apply_filter(Src & src, color_blind_tritanope const& op)
|
||||||
{
|
{
|
||||||
color_blind_filter(src, op);
|
apply_color_blind_filter(src, op);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Src>
|
template <typename Src>
|
||||||
|
|
|
@ -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 <mapnik/config.hpp>
|
|
||||||
#include <mapnik/css_color_grammar.hpp>
|
|
||||||
#include <mapnik/color.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
// stl
|
|
||||||
#include <cmath>
|
|
||||||
|
|
||||||
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 <typename Iterator, typename ContType>
|
|
||||||
struct image_filter_grammar :
|
|
||||||
qi::grammar<Iterator, ContType(), qi::ascii::space_type>
|
|
||||||
{
|
|
||||||
using alternative_type = qi::rule<Iterator, ContType(), qi::ascii::space_type>;
|
|
||||||
|
|
||||||
image_filter_grammar();
|
|
||||||
|
|
||||||
qi::rule<Iterator, ContType(), qi::ascii::space_type> start;
|
|
||||||
qi::rule<Iterator, ContType(), qi::ascii::space_type,
|
|
||||||
qi::locals<alternative_type*>> filter;
|
|
||||||
qi::rule<Iterator, qi::ascii::space_type> no_args;
|
|
||||||
qi::symbols<char, alternative_type*> alternatives;
|
|
||||||
qi::uint_parser< unsigned, 10, 1, 3 > radius_;
|
|
||||||
css_color_grammar<Iterator> css_color_;
|
|
||||||
qi::rule<Iterator, filter::color_stop(), qi::ascii::space_type> color_stop_;
|
|
||||||
qi::rule<Iterator, double(), qi::ascii::space_type> 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
|
|
|
@ -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 <mapnik/image_filter_types.hpp>
|
|
||||||
#include <mapnik/image_filter_grammar.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace { // internal
|
|
||||||
|
|
||||||
BOOST_PHOENIX_ADAPT_FUNCTION(
|
|
||||||
typename std::remove_reference<A1>::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 <typename Iterator, typename ContType>
|
|
||||||
image_filter_grammar<Iterator,ContType>::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_impl> percent_offset;
|
|
||||||
|
|
||||||
start = -(filter % *lit(','))
|
|
||||||
;
|
|
||||||
|
|
||||||
filter = omit[alternatives[_a = _1]] >> qi::lazy(*_a)
|
|
||||||
;
|
|
||||||
|
|
||||||
add("emboss") = no_args >> attr(construct<mapnik::filter::emboss>());
|
|
||||||
add("blur") = no_args >> attr(construct<mapnik::filter::blur>());
|
|
||||||
add("gray") = no_args >> attr(construct<mapnik::filter::gray>());
|
|
||||||
add("edge-detect") = no_args >> attr(construct<mapnik::filter::edge_detect>());
|
|
||||||
add("sobel") = no_args >> attr(construct<mapnik::filter::sobel>());
|
|
||||||
add("sharpen") = no_args >> attr(construct<mapnik::filter::sharpen>());
|
|
||||||
add("x-gradient") = no_args >> attr(construct<mapnik::filter::x_gradient>());
|
|
||||||
add("y-gradient") = no_args >> attr(construct<mapnik::filter::y_gradient>());
|
|
||||||
add("invert") = no_args >> attr(construct<mapnik::filter::invert>());
|
|
||||||
add("color-blind-protanope") = no_args >> attr(construct<mapnik::filter::color_blind_protanope>());
|
|
||||||
add("color-blind-deuteranope") = no_args >> attr(construct<mapnik::filter::color_blind_deuteranope>());
|
|
||||||
add("color-blind-tritanope") = no_args >> attr(construct<mapnik::filter::color_blind_tritanope>());
|
|
||||||
|
|
||||||
add("agg-stack-blur") =
|
|
||||||
(lit('(') >> radius_ >> -( lit(',') >> radius_ ) >> lit(')'))
|
|
||||||
[push_back(_val, construct<filter::agg_stack_blur>(_1, ovo(_2, _1)))]
|
|
||||||
|
|
|
||||||
no_args
|
|
||||||
[push_back(_val, construct<filter::agg_stack_blur>(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<filter::scale_hsla>(_1,_2,_3,_4,_5,_6,_7,_8))]
|
|
||||||
;
|
|
||||||
|
|
||||||
add("colorize-alpha") = qi::as<filter::colorize_alpha>()
|
|
||||||
[lit('(') >> color_stop_ % lit(',') >> lit(')')]
|
|
||||||
[push_back(_val, _1)]
|
|
||||||
;
|
|
||||||
|
|
||||||
color_stop_ = (css_color_ >> -color_stop_offset)
|
|
||||||
[_val = construct<filter::color_stop>(_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<filter::color_to_alpha>(_1))]
|
|
||||||
;
|
|
||||||
|
|
||||||
no_args = -(lit('(') >> lit(')'));
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Iterator, typename ContType>
|
|
||||||
auto image_filter_grammar<Iterator, ContType>::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
|
|
56
include/mapnik/image_filter_grammar_x3.hpp
Normal file
56
include/mapnik/image_filter_grammar_x3.hpp
Normal file
|
@ -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 <mapnik/image_filter.hpp>
|
||||||
|
#include <mapnik/image_filter_types.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#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<image_filter_class, std::vector<filter::filter_type> >;
|
||||||
|
|
||||||
|
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
|
261
include/mapnik/image_filter_grammar_x3_def.hpp
Normal file
261
include/mapnik/image_filter_grammar_x3_def.hpp
Normal file
|
@ -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 <mapnik/image_filter_grammar_x3.hpp>
|
||||||
|
#include <mapnik/image_filter_types.hpp>
|
||||||
|
#include <mapnik/css_color_grammar_x3.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#include <boost/spirit/home/x3/support/ast/variant.hpp>
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
|
#include <boost/fusion/adapted/std_tuple.hpp> // 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<unsigned, 10, 1, 3> radius;
|
||||||
|
|
||||||
|
// Import the expression rule
|
||||||
|
namespace { auto const& css_color = color_grammar(); }
|
||||||
|
|
||||||
|
// starting rule
|
||||||
|
image_filter_grammar_type const start("start");
|
||||||
|
// rules
|
||||||
|
x3::rule<class filter_class, filter::filter_type > const filter("filter");
|
||||||
|
|
||||||
|
x3::rule<class emboss_class, filter::emboss> const emboss_filter("emboss");
|
||||||
|
x3::rule<class blur_class, filter::blur> const blur_filter("blur");
|
||||||
|
x3::rule<class gray_class, filter::gray> const gray_filter("gray");
|
||||||
|
x3::rule<class edge_detect_class, filter::edge_detect> const edge_detect_filter("edge-detect");
|
||||||
|
x3::rule<class sobel_class, filter::sobel> const sobel_filter("sobel");
|
||||||
|
x3::rule<class sharpen_class, filter::sharpen> const sharpen_filter("sharpen");
|
||||||
|
x3::rule<class x_gradient_class, filter::x_gradient> const x_gradient_filter("x-gradient");
|
||||||
|
x3::rule<class y_gradient_class, filter::y_gradient> const y_gradient_filter("y-gradient");
|
||||||
|
x3::rule<class invert_class, filter::invert> const invert_filter("invert");
|
||||||
|
x3::rule<class color_blind_protanope_class, filter::color_blind_protanope> const color_blind_protanope_filter("color-blind-protanope");
|
||||||
|
x3::rule<class color_blind_deuteranope_class, filter::color_blind_deuteranope> const color_blind_deuteranope_filter("color-blind-deuteranope");
|
||||||
|
x3::rule<class color_blind_tritanope_class, filter::color_blind_tritanope> const color_blind_tritanope_filter("color-blind-tritanope");
|
||||||
|
|
||||||
|
x3::rule<class agg_blur_class, filter::agg_stack_blur> const agg_blur_filter("agg blur filter");
|
||||||
|
x3::rule<class scale_hsla_class, filter::scale_hsla> const scale_hsla_filter("scale-hsla");
|
||||||
|
x3::rule<class colorize_alpha_class, filter::colorize_alpha> const colorize_alpha_filter("colorize-alpha");
|
||||||
|
x3::rule<class color_stop_class, filter::color_stop> const color_stop("color-stop");
|
||||||
|
x3::rule<class offset_class, double> const offset("color-stop-offset");
|
||||||
|
x3::rule<class color_to_alpha_class, filter::color_to_alpha> 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 <mapnik/warning_ignore.hpp>
|
||||||
|
|
||||||
|
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
|
|
@ -56,32 +56,41 @@ struct y_gradient : image_filter_base {};
|
||||||
struct invert : image_filter_base {};
|
struct invert : image_filter_base {};
|
||||||
|
|
||||||
// http://vision.psychol.cam.ac.uk/jdmollon/papers/colourmaps.pdf
|
// 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;
|
color_blind_filter(double x_, double y_, double m_, double yint_)
|
||||||
const double y = 0.2535;
|
: x(x_), y(y_), m(m_), yint(yint_) {}
|
||||||
const double m = 1.273463;
|
double x;
|
||||||
const double yint = -0.073894;
|
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;
|
color_blind_protanope()
|
||||||
const double y = -0.4;
|
: color_blind_filter(0.7465, 0.2535, 1.273463, -0.073894) {}
|
||||||
const double m = 0.968437;
|
|
||||||
const double yint = 0.003331;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct color_blind_tritanope : image_filter_base
|
struct color_blind_deuteranope : color_blind_filter
|
||||||
{
|
{
|
||||||
const double x = 0.1748;
|
color_blind_deuteranope()
|
||||||
const double y = 0.0;
|
: color_blind_filter(1.4, -0.4, 0.968437, 0.003331) {}
|
||||||
const double m = 0.062921;
|
|
||||||
const double yint = 0.292119;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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
|
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_)
|
agg_stack_blur(unsigned rx_, unsigned ry_)
|
||||||
: rx(rx_),ry(ry_) {}
|
: rx(rx_),ry(ry_) {}
|
||||||
inline bool operator==(agg_stack_blur const& rhs) const
|
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
|
struct color_to_alpha : image_filter_base
|
||||||
{
|
{
|
||||||
|
color_to_alpha() {}
|
||||||
color_to_alpha(mapnik::color const& c)
|
color_to_alpha(mapnik::color const& c)
|
||||||
: color(c) {}
|
: color(c) {}
|
||||||
inline bool operator==(color_to_alpha const& rhs) const
|
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
|
struct scale_hsla : image_filter_base
|
||||||
{
|
{
|
||||||
|
scale_hsla() {}
|
||||||
scale_hsla(double _h0, double _h1,
|
scale_hsla(double _h0, double _h1,
|
||||||
double _s0, double _s1,
|
double _s0, double _s1,
|
||||||
double _l0, double _l1,
|
double _l0, double _l1,
|
||||||
|
|
|
@ -36,6 +36,8 @@
|
||||||
#include <boost/spirit/include/phoenix_function.hpp>
|
#include <boost/spirit/include/phoenix_function.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik { namespace json {
|
namespace mapnik { namespace json {
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace qi = boost::spirit::qi;
|
||||||
|
|
|
@ -23,11 +23,11 @@
|
||||||
#ifndef MAPNIK_MAKE_UNIQUE_HPP
|
#ifndef MAPNIK_MAKE_UNIQUE_HPP
|
||||||
#define MAPNIK_MAKE_UNIQUE_HPP
|
#define MAPNIK_MAKE_UNIQUE_HPP
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11
|
// http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11
|
||||||
#if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L
|
#if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
|
|
||||||
// C++14 backfill from http://herbsutter.com/gotw/_102/
|
// C++14 backfill from http://herbsutter.com/gotw/_102/
|
||||||
|
|
|
@ -331,7 +331,6 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status init_vertices()
|
status init_vertices()
|
||||||
{
|
{
|
||||||
if (status_ != initial) // already initialized
|
if (status_ != initial) // already initialized
|
||||||
|
@ -482,6 +481,7 @@ private:
|
||||||
}
|
}
|
||||||
start_v2.x = v2.x;
|
start_v2.x = v2.x;
|
||||||
start_v2.y = v2.y;
|
start_v2.y = v2.y;
|
||||||
|
|
||||||
vertex2d tmp_prev(vertex2d::no_init);
|
vertex2d tmp_prev(vertex2d::no_init);
|
||||||
|
|
||||||
while (i < points.size())
|
while (i < points.size())
|
||||||
|
|
|
@ -70,9 +70,9 @@ public:
|
||||||
return static_cast<bool>(type_ >> geometry_bits);
|
return static_cast<bool>(type_ >> geometry_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_type(types type)
|
void set_type(types _type)
|
||||||
{
|
{
|
||||||
type_ = type;
|
type_ = _type;
|
||||||
}
|
}
|
||||||
|
|
||||||
container_type const& data() const
|
container_type const& data() const
|
||||||
|
|
|
@ -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 <mapnik/path_expression_grammar.hpp>
|
|
||||||
#include <mapnik/attribute.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_object.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
namespace mapnik
|
|
||||||
{
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
path_expression_grammar<Iterator>::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<mapnik::attribute>( _1 )) ] >> ']')
|
|
||||||
)
|
|
||||||
;
|
|
||||||
|
|
||||||
attr %= +(char_ - ']');
|
|
||||||
str %= lexeme[+(char_ -'[')];
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
44
include/mapnik/path_expression_grammar_x3.hpp
Normal file
44
include/mapnik/path_expression_grammar_x3.hpp
Normal file
|
@ -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 <mapnik/path_expression.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#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<path_expression_class, path_expression>;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_DECLARE(path_expression_grammar_type);
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_X3_HPP
|
63
include/mapnik/path_expression_grammar_x3_def.hpp
Normal file
63
include/mapnik/path_expression_grammar_x3_def.hpp
Normal file
|
@ -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 <mapnik/path_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/attribute.hpp>
|
||||||
|
|
||||||
|
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<class attr_expression, std::string> const attr_expression("attribute");
|
||||||
|
x3::rule<class str_expression, std::string> 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
|
|
@ -27,8 +27,10 @@
|
||||||
#include <mapnik/box2d.hpp>
|
#include <mapnik/box2d.hpp>
|
||||||
#include <mapnik/util/noncopyable.hpp>
|
#include <mapnik/util/noncopyable.hpp>
|
||||||
#include <mapnik/make_unique.hpp>
|
#include <mapnik/make_unique.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <algorithm>
|
#include <memory>
|
||||||
|
#include <new>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
@ -83,12 +85,12 @@ class quad_tree : util::noncopyable
|
||||||
|
|
||||||
int num_subnodes() const
|
int num_subnodes() const
|
||||||
{
|
{
|
||||||
int count = 0;
|
int _count = 0;
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
if (children_[i]) ++count;
|
if (children_[i]) ++_count;
|
||||||
}
|
}
|
||||||
return count;
|
return _count;
|
||||||
}
|
}
|
||||||
~node () {}
|
~node () {}
|
||||||
};
|
};
|
||||||
|
@ -164,9 +166,9 @@ public:
|
||||||
|
|
||||||
int count_items() const
|
int count_items() const
|
||||||
{
|
{
|
||||||
int count = 0;
|
int _count = 0;
|
||||||
count_items(root_, count);
|
count_items(root_, _count);
|
||||||
return count;
|
return _count;
|
||||||
}
|
}
|
||||||
void trim()
|
void trim()
|
||||||
{
|
{
|
||||||
|
@ -276,23 +278,23 @@ private:
|
||||||
if (!n) return 0;
|
if (!n) return 0;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int count = 1;
|
int _count = 1;
|
||||||
for (int i = 0; i < 4; ++i)
|
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)
|
if (n)
|
||||||
{
|
{
|
||||||
count += n->cont_.size();
|
_count += n->cont_.size();
|
||||||
for (int i = 0; i < 4; ++i)
|
for (int i = 0; i < 4; ++i)
|
||||||
{
|
{
|
||||||
count_items(n->children_[i],count);
|
count_items(n->children_[i],_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,12 @@ public:
|
||||||
using resolution_type = std::tuple<double,double>;
|
using resolution_type = std::tuple<double,double>;
|
||||||
|
|
||||||
query(box2d<double> const& bbox,
|
query(box2d<double> const& bbox,
|
||||||
resolution_type const& resolution,
|
resolution_type const& _resolution,
|
||||||
double scale_denominator,
|
double _scale_denominator,
|
||||||
box2d<double> const& unbuffered_bbox)
|
box2d<double> const& unbuffered_bbox)
|
||||||
: bbox_(bbox),
|
: bbox_(bbox),
|
||||||
resolution_(resolution),
|
resolution_(_resolution),
|
||||||
scale_denominator_(scale_denominator),
|
scale_denominator_(_scale_denominator),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
unbuffered_bbox_(unbuffered_bbox),
|
unbuffered_bbox_(unbuffered_bbox),
|
||||||
names_(),
|
names_(),
|
||||||
|
@ -53,11 +53,11 @@ public:
|
||||||
{}
|
{}
|
||||||
|
|
||||||
query(box2d<double> const& bbox,
|
query(box2d<double> const& bbox,
|
||||||
resolution_type const& resolution,
|
resolution_type const& _resolution,
|
||||||
double scale_denominator = 1.0)
|
double _scale_denominator = 1.0)
|
||||||
: bbox_(bbox),
|
: bbox_(bbox),
|
||||||
resolution_(resolution),
|
resolution_(_resolution),
|
||||||
scale_denominator_(scale_denominator),
|
scale_denominator_(_scale_denominator),
|
||||||
filter_factor_(1.0),
|
filter_factor_(1.0),
|
||||||
unbuffered_bbox_(bbox),
|
unbuffered_bbox_(bbox),
|
||||||
names_(),
|
names_(),
|
||||||
|
|
|
@ -52,9 +52,9 @@ public:
|
||||||
data_(std::move(data)),
|
data_(std::move(data)),
|
||||||
filter_factor_(filter_factor) {}
|
filter_factor_(filter_factor) {}
|
||||||
|
|
||||||
void set_nodata(double nodata)
|
void set_nodata(double _nodata)
|
||||||
{
|
{
|
||||||
nodata_ = nodata;
|
nodata_ = _nodata;
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<double> const& nodata() const
|
boost::optional<double> const& nodata() const
|
||||||
|
|
|
@ -176,9 +176,9 @@ public:
|
||||||
|
|
||||||
span_image_resample_rgba_affine(source_type & src,
|
span_image_resample_rgba_affine(source_type & src,
|
||||||
interpolator_type & inter,
|
interpolator_type & inter,
|
||||||
agg::image_filter_lut const & filter,
|
agg::image_filter_lut const & _filter,
|
||||||
boost::optional<value_type> const & nodata_value) :
|
boost::optional<value_type> const & nodata_value) :
|
||||||
agg::span_image_resample_rgba_affine<Source>(src, inter, filter)
|
agg::span_image_resample_rgba_affine<Source>(src, inter, _filter)
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -121,12 +121,12 @@ namespace mapnik { namespace svg {
|
||||||
fill_color_("#000000")
|
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),
|
: x_(x),
|
||||||
y_(y),
|
y_(y),
|
||||||
width_(width),
|
width_(width),
|
||||||
height_(height),
|
height_(height),
|
||||||
fill_color_(fill_color.to_hex_string())
|
fill_color_(_fill_color.to_hex_string())
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void set_x(const int x);
|
void set_x(const int x);
|
||||||
|
|
|
@ -131,9 +131,9 @@ public:
|
||||||
return painted_;
|
return painted_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void painted(bool painted)
|
void painted(bool _painted)
|
||||||
{
|
{
|
||||||
painted_ = painted;
|
painted_ = _painted;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
inline eAttributeCollectionPolicy attribute_collection_policy() const
|
||||||
|
|
|
@ -50,8 +50,8 @@ private:
|
||||||
class text_placement_info_list : public text_placement_info
|
class text_placement_info_list : public text_placement_info
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
text_placement_info_list(text_placements_list const* parent, double scale_factor) :
|
text_placement_info_list(text_placements_list const* parent, double _scale_factor) :
|
||||||
text_placement_info(parent, scale_factor),
|
text_placement_info(parent, _scale_factor),
|
||||||
state(0), parent_(parent) {}
|
state(0), parent_(parent) {}
|
||||||
bool next() const;
|
bool next() const;
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -55,6 +55,8 @@ struct matrix_node
|
||||||
expr_node e_;
|
expr_node e_;
|
||||||
expr_node f_;
|
expr_node f_;
|
||||||
|
|
||||||
|
matrix_node() = default;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
explicit matrix_node(T const& m)
|
explicit matrix_node(T const& m)
|
||||||
: a_(m.sx), b_(m.shy), c_(m.shx), d_(m.sy), e_(m.tx), f_(m.ty) {}
|
: 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 tx_;
|
||||||
expr_node ty_;
|
expr_node ty_;
|
||||||
|
|
||||||
|
translate_node() = default;
|
||||||
|
|
||||||
translate_node(expr_node const& tx,
|
translate_node(expr_node const& tx,
|
||||||
boost::optional<expr_node> const& ty)
|
boost::optional<expr_node> const& ty)
|
||||||
: tx_(tx)
|
: tx_(tx)
|
||||||
|
@ -80,6 +84,8 @@ struct scale_node
|
||||||
expr_node sx_;
|
expr_node sx_;
|
||||||
expr_node sy_;
|
expr_node sy_;
|
||||||
|
|
||||||
|
scale_node() = default;
|
||||||
|
|
||||||
scale_node(expr_node const& sx,
|
scale_node(expr_node const& sx,
|
||||||
boost::optional<expr_node> const& sy)
|
boost::optional<expr_node> const& sy)
|
||||||
: sx_(sx)
|
: sx_(sx)
|
||||||
|
@ -94,6 +100,8 @@ struct rotate_node
|
||||||
expr_node cx_;
|
expr_node cx_;
|
||||||
expr_node cy_;
|
expr_node cy_;
|
||||||
|
|
||||||
|
rotate_node() = default;
|
||||||
|
|
||||||
explicit rotate_node(expr_node const& angle)
|
explicit rotate_node(expr_node const& angle)
|
||||||
: angle_(angle) {}
|
: angle_(angle) {}
|
||||||
|
|
||||||
|
@ -123,16 +131,16 @@ struct rotate_node
|
||||||
struct skewX_node
|
struct skewX_node
|
||||||
{
|
{
|
||||||
expr_node angle_;
|
expr_node angle_;
|
||||||
|
skewX_node() = default;
|
||||||
explicit skewX_node(expr_node const& angle)
|
skewX_node(expr_node const& angle)
|
||||||
: angle_(angle) {}
|
: angle_(angle) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct skewY_node
|
struct skewY_node
|
||||||
{
|
{
|
||||||
expr_node angle_;
|
expr_node angle_;
|
||||||
|
skewY_node() = default;
|
||||||
explicit skewY_node(expr_node const& angle)
|
skewY_node(expr_node const& angle)
|
||||||
: angle_(angle) {}
|
: angle_(angle) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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 <mapnik/expression_grammar.hpp>
|
|
||||||
#include <mapnik/expression_node_types.hpp>
|
|
||||||
#include <mapnik/transform_expression.hpp>
|
|
||||||
|
|
||||||
// spirit
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
struct transform_expression_grammar
|
|
||||||
: qi::grammar<Iterator, transform_list(), space_type>
|
|
||||||
{
|
|
||||||
explicit transform_expression_grammar();
|
|
||||||
|
|
||||||
using node_rule = qi::rule<Iterator, transform_node(), space_type>;
|
|
||||||
using list_rule = qi::rule<Iterator, transform_list(), space_type>;
|
|
||||||
|
|
||||||
// rules
|
|
||||||
qi::rule<Iterator, std::string(), space_type> attr;
|
|
||||||
qi::rule<Iterator, expr_node(), space_type> atom;
|
|
||||||
qi::rule<Iterator, expr_node(), space_type> expr;
|
|
||||||
qi::rule<Iterator, expr_node(), space_type> sep_atom;
|
|
||||||
qi::rule<Iterator, expr_node(), space_type> sep_expr;
|
|
||||||
qi::rule<Iterator, transform_list(), space_type> start;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> transform_;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> matrix;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> translate;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> scale;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> rotate;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> skewX;
|
|
||||||
qi::rule<Iterator, transform_node(), space_type> skewY;
|
|
||||||
mapnik::expression_grammar<Iterator> g_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace mapnik
|
|
||||||
|
|
||||||
#endif // MAPNIK_TRANSFORM_EXPRESSION_GRAMMAR_HPP
|
|
|
@ -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 <mapnik/transform_expression_grammar.hpp>
|
|
||||||
|
|
||||||
// boost
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_object.hpp>
|
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik {
|
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
|
|
||||||
template <typename Iterator>
|
|
||||||
transform_expression_grammar<Iterator>::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 <transform-list>, 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(<a> <b> <c> <d> <e> <f>)
|
|
||||||
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<matrix_node>(_1,_2,_3,_4,_5,_6) ];
|
|
||||||
|
|
||||||
// translate(<tx> [<ty>])
|
|
||||||
translate = no_case[lit("translate")]
|
|
||||||
>> lit('(')
|
|
||||||
>> ( ( atom >> -sep_atom >> lit(')') )
|
|
||||||
[ _val = construct<translate_node>(_1,_2) ]
|
|
||||||
| ( expr >> -sep_expr >> lit(')') )
|
|
||||||
[ _val = construct<translate_node>(_1,_2) ]
|
|
||||||
);
|
|
||||||
|
|
||||||
// scale(<sx> [<sy>])
|
|
||||||
scale = no_case[lit("scale")]
|
|
||||||
>> lit('(')
|
|
||||||
>> ( ( atom >> -sep_atom >> lit(')') )
|
|
||||||
[ _val = construct<scale_node>(_1,_2) ]
|
|
||||||
| ( expr >> -sep_expr >> lit(')') )
|
|
||||||
[ _val = construct<scale_node>(_1,_2) ]
|
|
||||||
);
|
|
||||||
|
|
||||||
// rotate(<rotate-angle> [<cx> <cy>])
|
|
||||||
rotate = no_case[lit("rotate")]
|
|
||||||
>> lit('(')
|
|
||||||
>> ( ( atom >> -( sep_atom >> sep_atom ) >> lit(')') )
|
|
||||||
[ _val = construct<rotate_node>(_1,_2) ]
|
|
||||||
| ( expr >> -( sep_expr >> sep_expr ) >> lit(')') )
|
|
||||||
[ _val = construct<rotate_node>(_1,_2) ]
|
|
||||||
);
|
|
||||||
|
|
||||||
// skewX(<skew-angle>)
|
|
||||||
skewX = no_case[lit("skewX")]
|
|
||||||
>> lit('(')
|
|
||||||
>> expr [ _val = construct<skewX_node>(_1) ]
|
|
||||||
>> lit(')');
|
|
||||||
|
|
||||||
// skewY(<skew-angle>)
|
|
||||||
skewY = no_case[lit("skewY")]
|
|
||||||
>> lit('(')
|
|
||||||
>> expr [ _val = construct<skewY_node>(_1) ]
|
|
||||||
>> lit(')');
|
|
||||||
|
|
||||||
// number or attribute
|
|
||||||
atom = double_ [ _val = _1 ]
|
|
||||||
| attr [ _val = construct<mapnik::attribute>(_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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -20,40 +20,32 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#ifndef MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
#ifndef MAPNIK_TRANSFORM_GRAMMAR_X3_HPP
|
||||||
#define MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
#define MAPNIK_TRANSFORM_GRAMMAR_X3_HPP
|
||||||
|
|
||||||
// mapnik
|
#include <mapnik/transform_expression.hpp>
|
||||||
#include <mapnik/path_expression.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
// stl
|
namespace mapnik {
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
namespace x3 = boost::spirit::x3;
|
||||||
|
|
||||||
|
namespace grammar {
|
||||||
|
|
||||||
|
struct transform_expression_class; // top-most ID
|
||||||
|
using transform_expression_grammar_type = x3::rule<transform_expression_class, mapnik::transform_list>;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_DECLARE(transform_expression_grammar_type);
|
||||||
|
|
||||||
|
}} // ns
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
grammar::transform_expression_grammar_type transform_expression_grammar();
|
||||||
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 <typename Iterator>
|
|
||||||
struct path_expression_grammar : qi::grammar<Iterator, std::vector<path_component>(), space_type>
|
|
||||||
{
|
|
||||||
path_expression_grammar();
|
|
||||||
qi::rule<Iterator, std::vector<path_component>() , space_type> expr;
|
|
||||||
qi::rule<Iterator, std::string() , space_type> attr;
|
|
||||||
qi::rule<Iterator, std::string() > str;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // MAPNIK_PATH_EXPRESSIONS_GRAMMAR_HPP
|
#endif
|
184
include/mapnik/transform_expression_grammar_x3_def.hpp
Normal file
184
include/mapnik/transform_expression_grammar_x3_def.hpp
Normal file
|
@ -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 <mapnik/transform_expression.hpp>
|
||||||
|
#include <mapnik/transform_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/expression_grammar_x3.hpp>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#include <boost/fusion/include/adapt_struct.hpp>
|
||||||
|
#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 <typename Source, typename Dest>
|
||||||
|
// 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, mapnik::detail::transform_node>(mapnik::skewX_node && src, mapnik::detail::transform_node& dst)
|
||||||
|
{
|
||||||
|
dst = std::move(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline void move_to<mapnik::skewY_node, mapnik::detail::transform_node>(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 <transform-list>, 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<class transform_list_class, mapnik::transform_list> transform_list_rule("transform list");
|
||||||
|
x3::rule<class transform_node_class, mapnik::transform_node> transform_node_rule("transform node");
|
||||||
|
x3::rule<class matrix_node_class, mapnik::matrix_node> matrix("matrix node");
|
||||||
|
x3::rule<class translate_node_class, mapnik::translate_node> translate("translate node");
|
||||||
|
x3::rule<class scale_node_class, mapnik::scale_node> scale("scale node");
|
||||||
|
x3::rule<class rotate_node_class, mapnik::rotate_node> rotate("rotate node");
|
||||||
|
x3::rule<class skewX_node_class, mapnik::skewX_node> skewX("skew X node");
|
||||||
|
x3::rule<class skewY_node_class, mapnik::skewY_node> 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(<a> <b> <c> <d> <e> <f>)
|
||||||
|
auto const matrix_def = no_case[lit("matrix")]
|
||||||
|
> '(' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ',' > expr > ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
// translate(<tx> [<ty>])
|
||||||
|
auto const translate_def = no_case[lit("translate")]
|
||||||
|
> '(' > expr > -(',' > expr ) > ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
// scale(<sx> [<sy>])
|
||||||
|
auto const scale_def = no_case[lit("scale")]
|
||||||
|
> '(' > expr > -(',' > expr ) > ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
// rotate(<rotate-angle> [<cx> <cy>])
|
||||||
|
auto const rotate_def = no_case[lit("rotate")]
|
||||||
|
> '(' > expr > -(',' > expr > ',' > expr) > ')'
|
||||||
|
;
|
||||||
|
|
||||||
|
// skewX(<skew-angle>)
|
||||||
|
auto const skewX_def = no_case[lit("skewX")]
|
||||||
|
> '(' > expr > ')';
|
||||||
|
|
||||||
|
// skewY(<skew-angle>)
|
||||||
|
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
|
|
@ -149,7 +149,7 @@ namespace std
|
||||||
{
|
{
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#pragma GCC diagnostic ignored "-Wmismatched-tags"
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
struct hash<mapnik::value>
|
struct hash<mapnik::value>
|
||||||
|
|
|
@ -54,4 +54,3 @@
|
||||||
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
|
#pragma GCC diagnostic ignored "-Wmissing-noreturn"
|
||||||
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
|
#pragma GCC diagnostic ignored "-Wcovered-switch-default"
|
||||||
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
#pragma GCC diagnostic ignored "-Wfloat-equal"
|
||||||
|
|
||||||
|
|
|
@ -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 EARTH_CIRCUMFERENCE = EARTH_DIAMETER * M_PI;
|
||||||
static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0;
|
static const double MAXEXTENT = EARTH_CIRCUMFERENCE / 2.0;
|
||||||
static const double M_PI_by2 = M_PI / 2;
|
static const double M_PI_by2 = M_PI / 2;
|
||||||
static const double D2R = M_PI / 180;
|
static const double D2R = M_PI / 180.0;
|
||||||
static const double R2D = 180 / M_PI;
|
static const double R2D = 180.0 / M_PI;
|
||||||
static const double M_PIby360 = M_PI / 360;
|
static const double M_PIby360 = M_PI / 360.0;
|
||||||
static const double MAXEXTENTby180 = MAXEXTENT / 180;
|
static const double MAXEXTENTby180 = MAXEXTENT / 180.0;
|
||||||
static const double MAX_LATITUDE = R2D * (2 * std::atan(std::exp(180 * D2R)) - M_PI_by2);
|
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_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";
|
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<well_known_srs_e> is_well_known_srs(std::string const& srs);
|
||||||
|
|
||||||
boost::optional<bool> is_known_geographic(std::string const& srs);
|
boost::optional<bool> 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<point_count; ++i)
|
for (std::size_t i = 0; i < point_count; ++i)
|
||||||
{
|
{
|
||||||
if (x[i] > 180) x[i] = 180;
|
if (x[i] > 180) x[i] = 180;
|
||||||
else if (x[i] < -180) x[i] = -180;
|
else if (x[i] < -180) x[i] = -180;
|
||||||
if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE;
|
if (y[i] > MAX_LATITUDE) y[i] = MAX_LATITUDE;
|
||||||
else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE;
|
else if (y[i] < -MAX_LATITUDE) y[i] = -MAX_LATITUDE;
|
||||||
x[i] = x[i] * MAXEXTENTby180;
|
x[i] = x[i] * MAXEXTENTby180;
|
||||||
y[i] = std::log(std::tan((90 + y[i]) * M_PIby360)) * R2D;
|
y[i] = std::log(std::tan((90.0 + y[i]) * M_PIby360)) * R2D * MAXEXTENTby180;
|
||||||
y[i] = y[i] * MAXEXTENTby180;
|
|
||||||
}
|
}
|
||||||
return true;
|
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<point_count; i++)
|
for(std::size_t i = 0; i < point_count; ++i)
|
||||||
{
|
{
|
||||||
if (x[i] > MAXEXTENT) x[i] = MAXEXTENT;
|
if (x[i] > MAXEXTENT) x[i] = MAXEXTENT;
|
||||||
else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT;
|
else if (x[i] < -MAXEXTENT) x[i] = -MAXEXTENT;
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
#if defined(MAPNIK_MEMORY_MAPPED_FILE)
|
||||||
#include <boost/interprocess/mapped_region.hpp>
|
#include <boost/interprocess/mapped_region.hpp>
|
||||||
#include <mapnik/mapped_memory_cache.hpp>
|
#include <mapnik/mapped_memory_cache.hpp>
|
||||||
|
@ -187,9 +187,9 @@ void dbf_file::add_attribute(int col, mapnik::transcoder const& tr, mapnik::feat
|
||||||
double val = 0.0;
|
double val = 0.0;
|
||||||
const char *itr = record_+fields_[col].offset_;
|
const char *itr = record_+fields_[col].offset_;
|
||||||
const char *end = itr + fields_[col].length_;
|
const char *end = itr + fields_[col].length_;
|
||||||
ascii::space_type space;
|
x3::ascii::space_type space;
|
||||||
static qi::double_type double_;
|
static x3::double_type double_;
|
||||||
if (qi::phrase_parse(itr,end,double_,space,val))
|
if (x3::phrase_parse(itr,end,double_,space,val))
|
||||||
{
|
{
|
||||||
f.put(name,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;
|
mapnik::value_integer val = 0;
|
||||||
const char *itr = record_+fields_[col].offset_;
|
const char *itr = record_+fields_[col].offset_;
|
||||||
const char *end = itr + fields_[col].length_;
|
const char *end = itr + fields_[col].length_;
|
||||||
ascii::space_type space;
|
x3::ascii::space_type space;
|
||||||
static qi::int_parser<mapnik::value_integer,10,1,-1> numeric_parser;
|
static x3::int_parser<mapnik::value_integer,10,1,-1> numeric_parser;
|
||||||
if (qi::phrase_parse(itr, end, numeric_parser, space, val))
|
if (x3::phrase_parse(itr, end, numeric_parser, space, val))
|
||||||
{
|
{
|
||||||
f.put(name,val);
|
f.put(name,val);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore_agg.hpp>
|
#include <mapnik/warning_ignore_agg.hpp>
|
||||||
|
|
14
src/build.py
14
src/build.py
|
@ -152,15 +152,17 @@ else: # unix, non-macos
|
||||||
|
|
||||||
source = Split(
|
source = Split(
|
||||||
"""
|
"""
|
||||||
expression_grammar.cpp
|
expression_grammar_x3.cpp
|
||||||
fs.cpp
|
fs.cpp
|
||||||
request.cpp
|
request.cpp
|
||||||
well_known_srs.cpp
|
well_known_srs.cpp
|
||||||
params.cpp
|
params.cpp
|
||||||
image_filter_types.cpp
|
parse_image_filters.cpp
|
||||||
image_filter_grammar.cpp
|
generate_image_filters.cpp
|
||||||
|
image_filter_grammar_x3.cpp
|
||||||
color.cpp
|
color.cpp
|
||||||
conversions.cpp
|
conversions_numeric.cpp
|
||||||
|
conversions_string.cpp
|
||||||
image_copy.cpp
|
image_copy.cpp
|
||||||
image_compositing.cpp
|
image_compositing.cpp
|
||||||
image_scaling.cpp
|
image_scaling.cpp
|
||||||
|
@ -173,6 +175,7 @@ source = Split(
|
||||||
expression_string.cpp
|
expression_string.cpp
|
||||||
expression.cpp
|
expression.cpp
|
||||||
transform_expression.cpp
|
transform_expression.cpp
|
||||||
|
transform_expression_grammar_x3.cpp
|
||||||
feature_kv_iterator.cpp
|
feature_kv_iterator.cpp
|
||||||
feature_style_processor.cpp
|
feature_style_processor.cpp
|
||||||
feature_type_style.cpp
|
feature_type_style.cpp
|
||||||
|
@ -199,7 +202,6 @@ source = Split(
|
||||||
load_map.cpp
|
load_map.cpp
|
||||||
palette.cpp
|
palette.cpp
|
||||||
marker_helpers.cpp
|
marker_helpers.cpp
|
||||||
transform_expression_grammar.cpp
|
|
||||||
geometry_envelope.cpp
|
geometry_envelope.cpp
|
||||||
plugin.cpp
|
plugin.cpp
|
||||||
rule.cpp
|
rule.cpp
|
||||||
|
@ -224,7 +226,7 @@ source = Split(
|
||||||
svg/svg_points_parser.cpp
|
svg/svg_points_parser.cpp
|
||||||
svg/svg_transform_parser.cpp
|
svg/svg_transform_parser.cpp
|
||||||
warp.cpp
|
warp.cpp
|
||||||
css_color_grammar.cpp
|
css_color_grammar_x3.cpp
|
||||||
vertex_cache.cpp
|
vertex_cache.cpp
|
||||||
vertex_adapters.cpp
|
vertex_adapters.cpp
|
||||||
text/font_library.cpp
|
text/font_library.cpp
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
// mapnik symbolizer generics
|
// mapnik symbolizer generics
|
||||||
#include <mapnik/renderer_common/render_group_symbolizer.hpp>
|
#include <mapnik/renderer_common/render_group_symbolizer.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,8 @@
|
||||||
#include <mapnik/agg_rasterizer.hpp>
|
#include <mapnik/agg_rasterizer.hpp>
|
||||||
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
#include <mapnik/renderer_common/apply_vertex_converter.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
// mapnik symbolizer generics
|
// mapnik symbolizer generics
|
||||||
#include <mapnik/renderer_common/process_raster_symbolizer.hpp>
|
#include <mapnik/renderer_common/process_raster_symbolizer.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -24,21 +24,20 @@
|
||||||
#include <mapnik/color.hpp>
|
#include <mapnik/color.hpp>
|
||||||
#include <mapnik/color_factory.hpp>
|
#include <mapnik/color_factory.hpp>
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/css_color_grammar.hpp>
|
#include <mapnik/css_color_grammar_x3.hpp>
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
|
||||||
color parse_color(std::string const& str)
|
color parse_color(std::string const& str)
|
||||||
{
|
{
|
||||||
// TODO - early return for @color?
|
// TODO - early return for @color?
|
||||||
static const css_color_grammar<std::string::const_iterator> g;
|
auto const& grammar = mapnik::color_grammar();
|
||||||
color c;
|
color c;
|
||||||
std::string::const_iterator first = str.begin();
|
std::string::const_iterator first = str.begin();
|
||||||
std::string::const_iterator last = str.end();
|
std::string::const_iterator last = str.end();
|
||||||
boost::spirit::ascii::space_type space;
|
using namespace boost::spirit::x3::ascii;
|
||||||
bool result = boost::spirit::qi::phrase_parse(first, last, g,
|
|
||||||
space,
|
bool result = boost::spirit::x3::phrase_parse(first, last, grammar, space, c);
|
||||||
c);
|
|
||||||
if (result && (first == last))
|
if (result && (first == last))
|
||||||
{
|
{
|
||||||
return c;
|
return c;
|
||||||
|
|
|
@ -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 <mapnik/util/conversions.hpp>
|
|
||||||
#include <mapnik/value_types.hpp>
|
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
// karma is used by default
|
|
||||||
#define MAPNIK_KARMA_TO_STRING
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#include <mapnik/warning_ignore.hpp>
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
#ifdef MAPNIK_KARMA_TO_STRING
|
|
||||||
#include <boost/spirit/include/karma.hpp>
|
|
||||||
#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<size_t>(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<std::string> 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<std::string> 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<std::string> sink(str);
|
|
||||||
return karma::generate(sink, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool to_string(std::string & str, bool value)
|
|
||||||
{
|
|
||||||
namespace karma = boost::spirit::karma;
|
|
||||||
std::back_insert_iterator<std::string> 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<size_t>(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<size_t>(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<size_t>(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
|
|
||||||
|
|
||||||
}
|
|
146
src/conversions_numeric.cpp
Normal file
146
src/conversions_numeric.cpp
Normal file
|
@ -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 <mapnik/util/conversions.hpp>
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#include <boost/spirit/home/x3.hpp>
|
||||||
|
#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
|
162
src/conversions_string.cpp
Normal file
162
src/conversions_string.cpp
Normal file
|
@ -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 <mapnik/util/conversions.hpp>
|
||||||
|
#include <mapnik/value_types.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cstring>
|
||||||
|
|
||||||
|
// karma is used by default
|
||||||
|
#define MAPNIK_KARMA_TO_STRING
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
#ifdef MAPNIK_KARMA_TO_STRING
|
||||||
|
#include <boost/spirit/include/karma.hpp>
|
||||||
|
#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<size_t>(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<std::string> 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<std::string> 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<std::string> sink(str);
|
||||||
|
return karma::generate(sink, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool to_string(std::string& str, bool value)
|
||||||
|
{
|
||||||
|
namespace karma = boost::spirit::karma;
|
||||||
|
std::back_insert_iterator<std::string> 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<size_t>(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<size_t>(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<size_t>(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
|
||||||
|
}
|
|
@ -20,10 +20,14 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/image_filter_grammar.hpp>
|
#include <mapnik/css_color_grammar_x3_def.hpp>
|
||||||
#include <mapnik/image_filter_grammar_impl.hpp>
|
|
||||||
#include <mapnik/image_filter_types.hpp>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
template struct mapnik::image_filter_grammar<std::string::const_iterator,std::vector<mapnik::filter::filter_type>>;
|
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<x3::ascii::space_type>::type;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(css_color_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}}
|
|
@ -25,11 +25,7 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_function.hpp>
|
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
namespace mapnik {
|
namespace mapnik {
|
||||||
|
@ -58,15 +54,14 @@ inline bool setup_dashes(std::vector<double> & buf, dash_array & dash)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool parse_dasharray(std::string const& value, dash_array & dash)
|
bool parse_dasharray(std::string const& value, dash_array & dash)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit;
|
using namespace boost::spirit;
|
||||||
qi::double_type double_;
|
using x3::no_skip;
|
||||||
qi::_1_type _1;
|
using x3::double_;
|
||||||
qi::lit_type lit;
|
using x3::char_;
|
||||||
qi::char_type char_;
|
boost::spirit::x3::ascii::space_type space;
|
||||||
qi::ascii::space_type space;
|
|
||||||
qi::no_skip_type no_skip;
|
|
||||||
// SVG
|
// SVG
|
||||||
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
|
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
|
||||||
// no support for 'percentage' as viewport is unknown at load_map
|
// 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<double> buf;
|
std::vector<double> buf;
|
||||||
auto first = value.begin();
|
auto first = value.begin();
|
||||||
auto last = value.end();
|
auto last = value.end();
|
||||||
bool r = qi::phrase_parse(first, last,
|
bool r = x3::phrase_parse(first, last,
|
||||||
(double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] %
|
(double_ % no_skip[char_(", ")] | "none"),
|
||||||
no_skip[char_(", ")]
|
space, buf);
|
||||||
| lit("none")),
|
|
||||||
space);
|
|
||||||
if (r && first == last)
|
if (r && first == last)
|
||||||
{
|
{
|
||||||
return setup_dashes(buf, dash);
|
return setup_dashes(buf, dash);
|
||||||
|
|
|
@ -25,27 +25,31 @@
|
||||||
#include <mapnik/config_error.hpp>
|
#include <mapnik/config_error.hpp>
|
||||||
#include <mapnik/unicode.hpp>
|
#include <mapnik/unicode.hpp>
|
||||||
#include <mapnik/expression_node_types.hpp>
|
#include <mapnik/expression_node_types.hpp>
|
||||||
#include <mapnik/expression_grammar.hpp>
|
#include <mapnik/expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/expression_grammar_x3_config.hpp>
|
||||||
// boost
|
|
||||||
#include <boost/spirit/include/qi.hpp>
|
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
expression_ptr parse_expression(std::string const& str)
|
expression_ptr parse_expression(std::string const& str)
|
||||||
{
|
{
|
||||||
static const expression_grammar<std::string::const_iterator> g;
|
|
||||||
boost::spirit::standard_wide::space_type space;
|
|
||||||
auto node = std::make_shared<expr_node>();
|
auto node = std::make_shared<expr_node>();
|
||||||
std::string::const_iterator itr = str.begin();
|
using boost::spirit::x3::ascii::space;
|
||||||
std::string::const_iterator end = str.end();
|
mapnik::transcoder const tr("utf8");
|
||||||
|
auto parser = boost::spirit::x3::with<mapnik::grammar::transcoder_tag>(std::ref(tr))
|
||||||
|
[
|
||||||
|
mapnik::expression_grammar()
|
||||||
|
];
|
||||||
|
|
||||||
bool r = false;
|
bool r = false;
|
||||||
|
std::string::const_iterator itr = str.begin();
|
||||||
|
std::string::const_iterator const end = str.end();
|
||||||
|
|
||||||
try
|
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<std::string::const_iterator> const& ex)
|
catch (boost::spirit::x3::expectation_failure<std::string::const_iterator> const& ex)
|
||||||
{
|
{
|
||||||
// no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error
|
// no need to show "boost::spirit::qi::expectation_failure" which is a std::runtime_error
|
||||||
throw config_error("Failed to parse expression: \"" + str + "\"");
|
throw config_error("Failed to parse expression: \"" + str + "\"");
|
||||||
|
|
|
@ -20,7 +20,11 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/transform_expression_grammar_impl.hpp>
|
#include <mapnik/expression_grammar_x3_def.hpp>
|
||||||
#include <string>
|
#include <mapnik/expression_grammar_x3_config.hpp>
|
||||||
|
|
||||||
template struct mapnik::transform_expression_grammar<std::string::const_iterator>;
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(expression_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}}
|
|
@ -148,9 +148,9 @@ std::vector<filter::filter_type> const& feature_type_style::direct_image_filter
|
||||||
return direct_filters_;
|
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<composite_mode_e> feature_type_style::comp_op() const
|
boost::optional<composite_mode_e> feature_type_style::comp_op() const
|
||||||
|
|
|
@ -48,7 +48,6 @@ extern "C"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
// mapnik
|
// mapnik
|
||||||
#include <mapnik/image_filter_types.hpp>
|
#include <mapnik/image_filter_types.hpp>
|
||||||
#include <mapnik/image_filter_grammar.hpp>
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
|
@ -43,18 +43,4 @@ bool generate_image_filters(std::back_insert_iterator<std::string> & sink, std::
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_image_filters(std::string const& filters, std::vector<filter_type>& image_filters)
|
|
||||||
{
|
|
||||||
std::string::const_iterator itr = filters.begin();
|
|
||||||
std::string::const_iterator end = filters.end();
|
|
||||||
static const mapnik::image_filter_grammar<std::string::const_iterator,
|
|
||||||
std::vector<mapnik::filter::filter_type> > 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}}
|
}}
|
|
@ -20,7 +20,6 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/geometry_envelope.hpp>
|
|
||||||
#include <mapnik/geometry_envelope_impl.hpp>
|
#include <mapnik/geometry_envelope_impl.hpp>
|
||||||
#include <mapnik/text/symbolizer_helpers.hpp>
|
#include <mapnik/text/symbolizer_helpers.hpp>
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <deque>
|
#include <deque>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore_agg.hpp>
|
#include <mapnik/warning_ignore_agg.hpp>
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
*
|
*
|
||||||
* This file is part of Mapnik (c++ mapping toolkit)
|
* 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
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* 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:
|
#include <mapnik/image_filter_grammar_x3_def.hpp>
|
||||||
// once by src/color_factory.cpp and once by include/mapnik/image_filter_grammar.hpp
|
|
||||||
// otherwise it would make sense to simply do `#include <mapnik/css_color_grammar_impl.hpp>`
|
|
||||||
// in a single file
|
|
||||||
#include <mapnik/color.hpp>
|
|
||||||
#include <mapnik/css_color_grammar_impl.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
template struct mapnik::css_color_grammar<std::string::const_iterator>;
|
namespace mapnik { namespace image_filter {
|
||||||
|
|
||||||
|
namespace x3 = boost::spirit::x3;
|
||||||
|
using iterator_type = std::string::const_iterator;
|
||||||
|
using context_type = x3::phrase_parse_context<x3::ascii::space_type>::type;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(image_filter_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}} // image_filter //mapnik
|
|
@ -24,49 +24,43 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/fusion/include/std_pair.hpp>
|
#include <boost/fusion/include/std_pair.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
namespace mapnik { namespace detail {
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace x3 = boost::spirit::x3;
|
||||||
|
|
||||||
template <typename Iterator>
|
using x3::lit;
|
||||||
struct image_options_grammar
|
using x3::ascii::char_;
|
||||||
: qi::grammar<Iterator, image_options_map(), boost::spirit::ascii::space_type>
|
|
||||||
{
|
|
||||||
using pair_type = std::pair<std::string, boost::optional<std::string>>;
|
using pair_type = std::pair<std::string, boost::optional<std::string>>;
|
||||||
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\\.\\-")
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
qi::rule<Iterator, image_options_map(), boost::spirit::ascii::space_type> start;
|
x3::rule<class image_options, image_options_map> const image_options("image options");
|
||||||
qi::rule<Iterator, pair_type(), boost::spirit::ascii::space_type> pair;
|
x3::rule<class key_value, pair_type> const key_value("key_value");
|
||||||
qi::rule<Iterator, std::string(), boost::spirit::ascii::space_type> key, value;
|
x3::rule<class key, std::string> const key("key");
|
||||||
};
|
x3::rule<class value, std::string> 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)
|
image_options_map parse_image_options(std::string const& str)
|
||||||
{
|
{
|
||||||
auto const begin = str.begin();
|
auto const begin = str.begin();
|
||||||
auto const end = str.end();
|
auto const end = str.end();
|
||||||
boost::spirit::ascii::space_type space;
|
using boost::spirit::x3::space;
|
||||||
mapnik::detail::image_options_grammar<std::string::const_iterator> g;
|
using mapnik::grammar::image_options;
|
||||||
image_options_map 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)
|
if (!success)
|
||||||
{
|
{
|
||||||
throw std::runtime_error("Can't parse image options: " + str);
|
throw std::runtime_error("Can't parse image options: " + str);
|
||||||
|
|
|
@ -31,9 +31,9 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
layer::layer(std::string const& name, std::string const& srs)
|
layer::layer(std::string const& _name, std::string const& _srs)
|
||||||
: name_(name),
|
: name_(_name),
|
||||||
srs_(srs),
|
srs_(_srs),
|
||||||
minimum_scale_denom_(0),
|
minimum_scale_denom_(0),
|
||||||
maximum_scale_denom_(std::numeric_limits<double>::max()),
|
maximum_scale_denom_(std::numeric_limits<double>::max()),
|
||||||
active_(true),
|
active_(true),
|
||||||
|
@ -114,9 +114,9 @@ bool layer::operator==(layer const& rhs) const
|
||||||
|
|
||||||
layer::~layer() {}
|
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
|
std::string const& layer::name() const
|
||||||
|
@ -124,9 +124,9 @@ std::string const& layer::name() const
|
||||||
return name_;
|
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
|
std::string const& layer::srs() const
|
||||||
|
@ -169,9 +169,9 @@ double layer::maximum_scale_denominator() const
|
||||||
return maximum_scale_denom_;
|
return maximum_scale_denom_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void layer::set_active(bool active)
|
void layer::set_active(bool _active)
|
||||||
{
|
{
|
||||||
active_=active;
|
active_ = _active;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool layer::active() const
|
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;
|
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
|
bool layer::queryable() const
|
||||||
|
@ -250,9 +250,9 @@ bool layer::clear_label_cache() const
|
||||||
return clear_label_cache_;
|
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
|
bool layer::cache_features() const
|
||||||
|
|
46
src/map.cpp
46
src/map.cpp
|
@ -375,39 +375,39 @@ unsigned Map::height() const
|
||||||
return height_;
|
return height_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::set_width(unsigned width)
|
void Map::set_width(unsigned _width)
|
||||||
{
|
{
|
||||||
if (width != width_ &&
|
if (_width != width_ &&
|
||||||
width >= MIN_MAPSIZE &&
|
_width >= MIN_MAPSIZE &&
|
||||||
width <= MAX_MAPSIZE)
|
_width <= MAX_MAPSIZE)
|
||||||
{
|
{
|
||||||
width_=width;
|
width_=_width;
|
||||||
fixAspectRatio();
|
fixAspectRatio();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::set_height(unsigned height)
|
void Map::set_height(unsigned _height)
|
||||||
{
|
{
|
||||||
if (height != height_ &&
|
if (_height != height_ &&
|
||||||
height >= MIN_MAPSIZE &&
|
_height >= MIN_MAPSIZE &&
|
||||||
height <= MAX_MAPSIZE)
|
_height <= MAX_MAPSIZE)
|
||||||
{
|
{
|
||||||
height_=height;
|
height_ = _height;
|
||||||
fixAspectRatio();
|
fixAspectRatio();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Map::resize(unsigned width,unsigned height)
|
void Map::resize(unsigned _width, unsigned _height)
|
||||||
{
|
{
|
||||||
if ((width != width_ ||
|
if ((_width != width_ ||
|
||||||
height != height_) &&
|
_height != height_) &&
|
||||||
width >= MIN_MAPSIZE &&
|
_width >= MIN_MAPSIZE &&
|
||||||
width <= MAX_MAPSIZE &&
|
_width <= MAX_MAPSIZE &&
|
||||||
height >= MIN_MAPSIZE &&
|
_height >= MIN_MAPSIZE &&
|
||||||
height <= MAX_MAPSIZE)
|
_height <= MAX_MAPSIZE)
|
||||||
{
|
{
|
||||||
width_=width;
|
width_ = _width;
|
||||||
height_=height;
|
height_ = _height;
|
||||||
fixAspectRatio();
|
fixAspectRatio();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,14 +417,14 @@ std::string const& Map::srs() const
|
||||||
return srs_;
|
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
|
int Map::buffer_size() const
|
||||||
|
|
|
@ -68,12 +68,12 @@ const char * memory_datasource::name()
|
||||||
return "memory";
|
return "memory";
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_datasource::memory_datasource(parameters const& params)
|
memory_datasource::memory_datasource(parameters const& _params)
|
||||||
: datasource(params),
|
: datasource(_params),
|
||||||
desc_(memory_datasource::name(),
|
desc_(memory_datasource::name(),
|
||||||
*params.get<std::string>("encoding","utf-8")),
|
*params_.get<std::string>("encoding","utf-8")),
|
||||||
type_(datasource::Vector),
|
type_(datasource::Vector),
|
||||||
bbox_check_(*params.get<boolean_type>("bbox_check", true)),
|
bbox_check_(*params_.get<boolean_type>("bbox_check", true)),
|
||||||
type_set_(false) {}
|
type_set_(false) {}
|
||||||
|
|
||||||
memory_datasource::~memory_datasource() {}
|
memory_datasource::~memory_datasource() {}
|
||||||
|
|
54
src/parse_image_filters.cpp
Normal file
54
src/parse_image_filters.cpp
Normal file
|
@ -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 <mapnik/image_filter_types.hpp>
|
||||||
|
#include <mapnik/image_filter_grammar_x3.hpp>
|
||||||
|
// stl
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace mapnik {
|
||||||
|
|
||||||
|
namespace filter {
|
||||||
|
|
||||||
|
bool parse_image_filters(std::string const& str, std::vector<filter_type> & 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
|
@ -21,26 +21,35 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/parse_path.hpp>
|
#include <mapnik/parse_path.hpp>
|
||||||
#include <mapnik/path_expression_grammar.hpp>
|
|
||||||
#include <mapnik/path_expression_grammar_impl.hpp>
|
|
||||||
#include <mapnik/config.hpp>
|
#include <mapnik/config.hpp>
|
||||||
#include <mapnik/attribute.hpp>
|
#include <mapnik/attribute.hpp>
|
||||||
#include <mapnik/feature.hpp>
|
#include <mapnik/feature.hpp>
|
||||||
#include <mapnik/value.hpp>
|
#include <mapnik/value.hpp>
|
||||||
|
|
||||||
|
#include <mapnik/path_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/path_expression_grammar_x3_def.hpp>
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
||||||
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<x3::standard_wide::space_type>::type;
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(path_expression_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
path_expression_ptr parse_path(std::string const& str)
|
path_expression_ptr parse_path(std::string const& str)
|
||||||
{
|
{
|
||||||
static const path_expression_grammar<std::string::const_iterator> g;
|
namespace x3 = boost::spirit::x3;
|
||||||
auto path = std::make_shared<path_expression>();
|
auto path = std::make_shared<path_expression>();
|
||||||
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 itr = str.begin();
|
||||||
std::string::const_iterator end = str.end();
|
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)
|
if (r && itr == end)
|
||||||
{
|
{
|
||||||
return path;
|
return path;
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include <mapnik/parse_transform.hpp>
|
#include <mapnik/parse_transform.hpp>
|
||||||
#include <mapnik/transform_expression_grammar.hpp>
|
#include <mapnik/transform_expression_grammar_x3.hpp>
|
||||||
|
#include <mapnik/expression_grammar_x3_config.hpp> // transcoder_tag
|
||||||
|
#include <mapnik/config_error.hpp>
|
||||||
// stl
|
// stl
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -31,14 +32,28 @@ namespace mapnik {
|
||||||
|
|
||||||
transform_list_ptr parse_transform(std::string const& str, std::string const& encoding)
|
transform_list_ptr parse_transform(std::string const& str, std::string const& encoding)
|
||||||
{
|
{
|
||||||
static const transform_expression_grammar<std::string::const_iterator> g;
|
using boost::spirit::x3::ascii::space;
|
||||||
transform_list_ptr tl = std::make_shared<transform_list>();
|
transform_list_ptr trans_list = std::make_shared<transform_list>();
|
||||||
std::string::const_iterator itr = str.begin();
|
std::string::const_iterator itr = str.begin();
|
||||||
std::string::const_iterator end = str.end();
|
std::string::const_iterator end = str.end();
|
||||||
bool r = qi::phrase_parse(itr, end, g, space_type(), *tl);
|
mapnik::transcoder const tr(encoding);
|
||||||
if (r && itr == end)
|
auto const parser = boost::spirit::x3::with<mapnik::grammar::transcoder_tag>(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<std::string::const_iterator> const& ex)
|
||||||
|
{
|
||||||
|
throw config_error("Failed to parse transform expression: \"" + str + "\"");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status && itr == end)
|
||||||
|
{
|
||||||
|
return trans_list;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,9 +41,8 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
#include <boost/fusion/adapted/struct.hpp>
|
||||||
#include <boost/spirit/include/phoenix_operator.hpp>
|
|
||||||
#include <boost/fusion/include/std_pair.hpp>
|
#include <boost/fusion/include/std_pair.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
|
#include <boost/property_tree/detail/xml_parser_read_rapidxml.hpp>
|
||||||
|
@ -55,6 +54,24 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
|
||||||
|
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 mapnik { namespace svg {
|
||||||
|
|
||||||
namespace rapidxml = boost::property_tree::detail::rapidxml;
|
namespace rapidxml = boost::property_tree::detail::rapidxml;
|
||||||
|
@ -77,29 +94,29 @@ void parse_attr(svg_parser & parser,rapidxml::xml_node<char> const* node);
|
||||||
void parse_attr(svg_parser & parser,char const * name, char const* value);
|
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<std::pair<double, agg::rgba8> >;
|
using color_lookup_type = std::vector<std::pair<double, agg::rgba8> >;
|
||||||
namespace qi = boost::spirit::qi;
|
|
||||||
using pairs_type = std::vector<std::pair<std::string, std::string> >;
|
using pairs_type = std::vector<std::pair<std::string, std::string> >;
|
||||||
|
|
||||||
template <typename Iterator,typename SkipType>
|
x3::rule<class key_value_sequence_ordered, pairs_type> const key_value_sequence_ordered("key_value_sequence_ordered");
|
||||||
struct key_value_sequence_ordered
|
x3::rule<class key_value, std::pair<std::string, std::string> > key_value("key_value");
|
||||||
: qi::grammar<Iterator, pairs_type(), SkipType>
|
x3::rule<class key, std::string> key("key");
|
||||||
{
|
x3::rule<class value_, std::string> value("value");
|
||||||
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(';'));
|
|
||||||
}
|
|
||||||
|
|
||||||
qi::rule<Iterator, pairs_type(), SkipType> query;
|
auto const key_def = x3::char_("a-zA-Z_") > *x3::char_("a-zA-Z_0-9-");
|
||||||
qi::rule<Iterator, std::pair<std::string, std::string>(), SkipType> pair;
|
auto const value_def = +(x3::char_ - ';');
|
||||||
qi::rule<Iterator, std::string(), SkipType> key, value;
|
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 <typename T>
|
template <typename T>
|
||||||
mapnik::color parse_color(T & error_messages, const char* str)
|
mapnik::color parse_color(T & error_messages, const char* str)
|
||||||
|
@ -126,8 +143,7 @@ agg::rgba8 parse_color_agg(T & error_messages, const char* str)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
double parse_double(T & error_messages, const char* str)
|
double parse_double(T & error_messages, const char* str)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit::qi;
|
using namespace boost::spirit::x3;
|
||||||
double_type double_;
|
|
||||||
double val = 0.0;
|
double val = 0.0;
|
||||||
if (!parse(str, str + std::strlen(str), double_, val))
|
if (!parse(str, str + std::strlen(str), double_, val))
|
||||||
{
|
{
|
||||||
|
@ -138,15 +154,11 @@ double parse_double(T & error_messages, const char* str)
|
||||||
|
|
||||||
// https://www.w3.org/TR/SVG/coords.html#Units
|
// https://www.w3.org/TR/SVG/coords.html#Units
|
||||||
template <typename T, int DPI = 90>
|
template <typename T, int DPI = 90>
|
||||||
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;
|
namespace x3 = boost::spirit::x3;
|
||||||
using boost::phoenix::ref;
|
|
||||||
qi::double_type double_;
|
|
||||||
qi::lit_type lit;
|
|
||||||
qi::_1_type _1;
|
|
||||||
double val = 0.0;
|
double val = 0.0;
|
||||||
qi::symbols<char, double> units;
|
x3::symbols<double> units;
|
||||||
units.add
|
units.add
|
||||||
("px", 1.0)
|
("px", 1.0)
|
||||||
("pt", DPI/72.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* cur = str; // phrase_parse modifies the first iterator
|
||||||
const char* end = str + std::strlen(str);
|
const char* end = str + std::strlen(str);
|
||||||
if (!qi::phrase_parse(cur, end,
|
|
||||||
double_[ref(val) = _1][ref(percent) = false]
|
auto apply_value = [&](auto const& ctx) { val = _attr(ctx); is_percent = false; };
|
||||||
> - (units[ ref(val) *= _1]
|
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]
|
||||||
|
|
|
|
||||||
lit('%')[ref(val) *= 0.01][ref(percent) = true]),
|
x3::lit('%')[apply_percent]),
|
||||||
skip_type()))
|
x3::space))
|
||||||
{
|
{
|
||||||
error_messages.emplace_back("Failed to parse SVG value: '" + std::string(str) + "'");
|
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;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T, typename V>
|
||||||
bool parse_double_list(T & error_messages, const char* str, double* list)
|
bool parse_viewbox(T & error_messages, const char* str, V & viewbox)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit::qi;
|
namespace x3 = boost::spirit::x3;
|
||||||
using boost::phoenix::ref;
|
if ( !x3::phrase_parse(str, str + std::strlen(str),
|
||||||
_1_type _1;
|
x3::double_ > -x3::lit(',') >
|
||||||
double_type double_;
|
x3::double_ > -x3::lit(',') >
|
||||||
lit_type lit;
|
x3::double_ > -x3::lit(',') >
|
||||||
using skip_type = boost::spirit::ascii::space_type;
|
x3::double_, x3::space, viewbox))
|
||||||
|
|
||||||
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()))
|
|
||||||
{
|
{
|
||||||
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 false;
|
||||||
}
|
}
|
||||||
return true;
|
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;
|
namespace x3 = boost::spirit::x3;
|
||||||
using skip_type = boost::spirit::ascii::space_type;
|
return x3::phrase_parse(str, str + std::strlen(str), grammar::key_value_sequence_ordered , x3::space, v);
|
||||||
key_value_sequence_ordered<const char*, skip_type> kv_parser;
|
|
||||||
return phrase_parse(str, str + std::strlen(str), kv_parser, skip_type(), v);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_id_from_url (char const* str, std::string & id)
|
bool parse_id_from_url (char const* str, std::string & id)
|
||||||
{
|
{
|
||||||
using namespace boost::spirit::qi;
|
namespace x3 = boost::spirit::x3;
|
||||||
using skip_type = boost::spirit::ascii::space_type;
|
auto extract_id = [&](auto const& ctx) { id += _attr(ctx); };
|
||||||
qi::_1_type _1;
|
return x3::phrase_parse(str, str + std::strlen(str),
|
||||||
qi::char_type char_;
|
x3::lit("url") > '(' > '#' > *(x3::char_ - ')')[extract_id] > ')',
|
||||||
qi::lit_type lit;
|
x3::space);
|
||||||
return phrase_parse(str, str + std::strlen(str),
|
|
||||||
lit("url") > "(" > "#" > *(char_ - lit(')'))[boost::phoenix::ref(id) += _1] > ")",
|
|
||||||
skip_type());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool traverse_tree(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
bool traverse_tree(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||||
|
@ -517,7 +523,7 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||||
double width = 0;
|
double width = 0;
|
||||||
double height = 0;
|
double height = 0;
|
||||||
double aspect_ratio = 1;
|
double aspect_ratio = 1;
|
||||||
double viewbox[4] = {0,0,0,0};
|
viewbox vbox = {0,0,0,0};
|
||||||
bool has_viewbox = false;
|
bool has_viewbox = false;
|
||||||
bool has_percent_height = true;
|
bool has_percent_height = true;
|
||||||
bool has_percent_width = true;
|
bool has_percent_width = true;
|
||||||
|
@ -535,23 +541,23 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||||
auto const* viewbox_attr = node->first_attribute("viewBox");
|
auto const* viewbox_attr = node->first_attribute("viewBox");
|
||||||
if (viewbox_attr)
|
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)
|
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;
|
width = aspect_ratio * height;
|
||||||
}
|
}
|
||||||
else if (!has_percent_width && has_percent_height && has_viewbox)
|
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;
|
height = height / aspect_ratio;
|
||||||
}
|
}
|
||||||
else if (has_percent_width && has_percent_height && has_viewbox)
|
else if (has_percent_width && has_percent_height && has_viewbox)
|
||||||
{
|
{
|
||||||
width = viewbox[2];
|
width = vbox.x1;
|
||||||
height = viewbox[3];
|
height = vbox.y1;
|
||||||
}
|
}
|
||||||
|
|
||||||
parser.path_.set_dimensions(width, height);
|
parser.path_.set_dimensions(width, height);
|
||||||
|
|
|
@ -93,11 +93,11 @@ void font_face_set::add(face_ptr face)
|
||||||
faces_.push_back(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_)
|
for (face_ptr const& face : faces_)
|
||||||
{
|
{
|
||||||
face->set_character_sizes(size);
|
face->set_character_sizes(_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,11 +26,10 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cctype>
|
#include <cctype>
|
||||||
|
@ -52,23 +51,14 @@ font_feature_settings::font_feature_settings()
|
||||||
void font_feature_settings::from_string(std::string const& features)
|
void font_feature_settings::from_string(std::string const& features)
|
||||||
{
|
{
|
||||||
features_.clear();
|
features_.clear();
|
||||||
|
|
||||||
if (std::all_of(features.begin(), features.end(), isspace)) return;
|
if (std::all_of(features.begin(), features.end(), isspace)) return;
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace x3 = boost::spirit::x3;
|
||||||
qi::char_type char_;
|
auto appender = [&](auto const& ctx)
|
||||||
qi::as_string_type as_string;
|
{
|
||||||
|
this->append(_attr(ctx));
|
||||||
#if BOOST_VERSION <= 104800
|
};
|
||||||
// Call correct overload.
|
if (!x3::parse(features.begin(), features.end(), (+(x3::char_ - ','))[appender] % ','))
|
||||||
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
|
|
||||||
|
|
||||||
{
|
{
|
||||||
throw config_error("failed to parse font-feature-settings: '" + features + "'");
|
throw config_error("failed to parse font-feature-settings: '" + features + "'");
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,9 +32,7 @@
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
#pragma GCC diagnostic push
|
||||||
#include <mapnik/warning_ignore.hpp>
|
#include <mapnik/warning_ignore.hpp>
|
||||||
#include <boost/spirit/include/qi.hpp>
|
#include <boost/spirit/home/x3.hpp>
|
||||||
#include <boost/spirit/include/phoenix_core.hpp>
|
|
||||||
#include <boost/spirit/include/phoenix_stl.hpp>
|
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
@ -43,12 +41,9 @@
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
namespace qi = boost::spirit::qi;
|
namespace x3 = boost::spirit::x3;
|
||||||
namespace phoenix = boost::phoenix;
|
|
||||||
using phoenix::push_back;
|
|
||||||
using phoenix::ref;
|
|
||||||
|
|
||||||
struct direction_name : qi::symbols<char, directions_e>
|
struct direction_name : x3::symbols<directions_e>
|
||||||
{
|
{
|
||||||
direction_name()
|
direction_name()
|
||||||
{
|
{
|
||||||
|
@ -64,8 +59,7 @@ struct direction_name : qi::symbols<char, directions_e>
|
||||||
("X" , EXACT_POSITION)
|
("X" , EXACT_POSITION)
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
} names;
|
||||||
};
|
|
||||||
|
|
||||||
// Position string: [POS][SIZE]
|
// Position string: [POS][SIZE]
|
||||||
// [POS] is any combination of
|
// [POS] is any combination of
|
||||||
|
@ -82,21 +76,15 @@ bool parse_positions(std::string const& evaluated_positions,
|
||||||
std::vector<directions_e> & direction,
|
std::vector<directions_e> & direction,
|
||||||
std::vector<int> & text_sizes)
|
std::vector<int> & text_sizes)
|
||||||
{
|
{
|
||||||
direction_name names;
|
auto push_back_direction = [&](auto const& ctx) { direction.push_back(_attr(ctx));};
|
||||||
boost::spirit::ascii::space_type space;
|
auto push_back_size = [&](auto const& ctx) { text_sizes.push_back(_attr(ctx));};
|
||||||
qi::_1_type _1;
|
auto const first = evaluated_positions.begin();
|
||||||
qi::float_type float_;
|
auto const last = evaluated_positions.end();
|
||||||
std::string::const_iterator first = evaluated_positions.begin();
|
bool r = x3::phrase_parse(first, last,
|
||||||
std::string::const_iterator last = evaluated_positions.end();
|
(names[push_back_direction] % ',')
|
||||||
bool r = qi::phrase_parse(first, last,
|
>> *(',' >> x3::float_[push_back_size]),
|
||||||
(names[push_back(phoenix::ref(direction), _1)] % ',')
|
x3::space);
|
||||||
>> *(',' >> float_[push_back(phoenix::ref(text_sizes), _1)]),
|
return (r && first != last);
|
||||||
space);
|
|
||||||
if (first != last)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -39,6 +39,8 @@
|
||||||
#include <boost/property_tree/ptree.hpp>
|
#include <boost/property_tree/ptree.hpp>
|
||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
using boost::optional;
|
using boost::optional;
|
||||||
|
|
|
@ -20,9 +20,11 @@
|
||||||
*
|
*
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
// NOTE: we define this here in a cpp because def is needed twice:
|
#include <mapnik/transform_expression_grammar_x3_def.hpp>
|
||||||
// once by src/expression.cpp and once by mapnik/transform_expression_grammar_impl.hpp
|
#include <mapnik/expression_grammar_x3_config.hpp>
|
||||||
#include <mapnik/expression_grammar_impl.hpp>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
template struct mapnik::expression_grammar<std::string::const_iterator>;
|
namespace mapnik { namespace grammar {
|
||||||
|
|
||||||
|
BOOST_SPIRIT_INSTANTIATE(transform_expression_grammar_type, iterator_type, context_type);
|
||||||
|
|
||||||
|
}}
|
|
@ -37,6 +37,7 @@ extern "C"
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,6 +29,8 @@
|
||||||
#include <mapnik/util/noncopyable.hpp>
|
#include <mapnik/util/noncopyable.hpp>
|
||||||
#include <mapnik/geometry_correct.hpp>
|
#include <mapnik/geometry_correct.hpp>
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
|
|
||||||
// stl
|
// stl
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace mapnik
|
namespace mapnik
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,63 +1,113 @@
|
||||||
|
|
||||||
#include "catch.hpp"
|
#include "catch.hpp"
|
||||||
#include <mapnik/css_color_grammar.hpp>
|
|
||||||
#include <mapnik/css_color_grammar_impl.hpp>
|
|
||||||
#include <mapnik/safe_cast.hpp>
|
#include <mapnik/safe_cast.hpp>
|
||||||
|
#include <mapnik/color.hpp>
|
||||||
|
#include <mapnik/css_color_grammar_x3.hpp>
|
||||||
|
#include <mapnik/css_color_grammar_x3_def.hpp>
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
TEST_CASE("css color") {
|
TEST_CASE("CSS color") {
|
||||||
|
|
||||||
SECTION("conversions")
|
SECTION("conversions")
|
||||||
{
|
{
|
||||||
mapnik::percent_conv_impl conv;
|
using namespace mapnik::css_color_grammar;
|
||||||
CHECK( conv(1.0) == 3 );
|
CHECK( percent_converter::call(1.0) == 3 );
|
||||||
CHECK( conv(60.0) == 153 );
|
CHECK( percent_converter::call(60.0) == 153 );
|
||||||
// should not overflow on invalid input
|
// should not overflow on invalid input
|
||||||
CHECK( conv(100000.0) == 255 );
|
CHECK( percent_converter::call(100000.0) == 255 );
|
||||||
CHECK( conv(-100000.0) == 0 );
|
CHECK( percent_converter::call(-100000.0) == 0 );
|
||||||
|
}
|
||||||
|
|
||||||
mapnik::alpha_conv_impl conv2;
|
SECTION("CSS colors")
|
||||||
CHECK( conv2(0.5) == 128 );
|
{
|
||||||
CHECK( conv2(1.0) == 255 );
|
auto const& color_grammar = mapnik::color_grammar();
|
||||||
// should not overflow on invalid input
|
boost::spirit::x3::ascii::space_type space;
|
||||||
CHECK( conv2(60.0) == 255 );
|
{
|
||||||
CHECK( conv2(100000.0) == 255 );
|
// rgb
|
||||||
CHECK( conv2(-100000.0) == 0 );
|
std::string s("rgb(128,0,255)");
|
||||||
|
|
||||||
mapnik::hsl_conv_impl conv3;
|
|
||||||
mapnik::color c;
|
mapnik::color c;
|
||||||
conv3(c, 1.0, 1.0, 1.0);
|
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.alpha() == 255 );
|
||||||
CHECK( c.red() == 3 );
|
CHECK( c.red() == 233 );
|
||||||
CHECK( c.green() == 3 );
|
CHECK( c.green() == 150 );
|
||||||
CHECK( c.blue() == 3 );
|
CHECK( c.blue() == 122 );
|
||||||
// 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 );
|
|
||||||
}
|
}
|
||||||
|
// hsl
|
||||||
SECTION("hex colors")
|
|
||||||
{
|
{
|
||||||
mapnik::css_color_grammar<std::string::const_iterator> color_grammar;
|
std::string s("hsl(240,50%,50%)");
|
||||||
boost::spirit::qi::ascii::space_type space;
|
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");
|
std::string s("#abcdef");
|
||||||
mapnik::color c;
|
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.alpha() == 0xff );
|
||||||
CHECK( c.red() == 0xab );
|
CHECK( c.red() == 0xab );
|
||||||
CHECK( c.green() == 0xcd );
|
CHECK( c.green() == 0xcd );
|
||||||
CHECK( c.blue() == 0xef );
|
CHECK( c.blue() == 0xef );
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string s("#abcdef12");
|
std::string s("#abcdef12");
|
||||||
mapnik::color c;
|
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.alpha() == 0x12 );
|
||||||
CHECK( c.red() == 0xab );
|
CHECK( c.red() == 0xab );
|
||||||
CHECK( c.green() == 0xcd );
|
CHECK( c.green() == 0xcd );
|
||||||
|
@ -67,7 +117,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s(" #abcdef");
|
std::string s(" #abcdef");
|
||||||
mapnik::color c;
|
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.alpha() == 0xff );
|
||||||
CHECK( c.red() == 0xab );
|
CHECK( c.red() == 0xab );
|
||||||
CHECK( c.green() == 0xcd );
|
CHECK( c.green() == 0xcd );
|
||||||
|
@ -77,7 +127,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s(" #abcdef12");
|
std::string s(" #abcdef12");
|
||||||
mapnik::color c;
|
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.alpha() == 0x12 );
|
||||||
CHECK( c.red() == 0xab );
|
CHECK( c.red() == 0xab );
|
||||||
CHECK( c.green() == 0xcd );
|
CHECK( c.green() == 0xcd );
|
||||||
|
@ -86,22 +136,26 @@ TEST_CASE("css color") {
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string s("# abcdef");
|
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");
|
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");
|
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");
|
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
|
// hex_color_small
|
||||||
|
@ -109,7 +163,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s("#abc");
|
std::string s("#abc");
|
||||||
mapnik::color c;
|
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.alpha() == 0xff );
|
||||||
CHECK( c.red() == 0xaa );
|
CHECK( c.red() == 0xaa );
|
||||||
CHECK( c.green() == 0xbb );
|
CHECK( c.green() == 0xbb );
|
||||||
|
@ -119,7 +173,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s("#abcd");
|
std::string s("#abcd");
|
||||||
mapnik::color c;
|
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.alpha() == 0xdd );
|
||||||
CHECK( c.red() == 0xaa );
|
CHECK( c.red() == 0xaa );
|
||||||
CHECK( c.green() == 0xbb );
|
CHECK( c.green() == 0xbb );
|
||||||
|
@ -129,7 +183,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s(" #abc");
|
std::string s(" #abc");
|
||||||
mapnik::color c;
|
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.alpha() == 0xff );
|
||||||
CHECK( c.red() == 0xaa );
|
CHECK( c.red() == 0xaa );
|
||||||
CHECK( c.green() == 0xbb );
|
CHECK( c.green() == 0xbb );
|
||||||
|
@ -139,7 +193,7 @@ TEST_CASE("css color") {
|
||||||
{
|
{
|
||||||
std::string s(" #abcd");
|
std::string s(" #abcd");
|
||||||
mapnik::color c;
|
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.alpha() == 0xdd );
|
||||||
CHECK( c.red() == 0xaa );
|
CHECK( c.red() == 0xaa );
|
||||||
CHECK( c.green() == 0xbb );
|
CHECK( c.green() == 0xbb );
|
||||||
|
@ -148,22 +202,26 @@ TEST_CASE("css color") {
|
||||||
|
|
||||||
{
|
{
|
||||||
std::string s("# abc");
|
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");
|
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");
|
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");
|
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()")
|
SECTION("operator<< / to_string()")
|
||||||
|
|
Loading…
Reference in a new issue