Merge branch 'master' of github.com:mapnik/mapnik into spirit-x3
This commit is contained in:
commit
4432e93250
23 changed files with 293 additions and 1073 deletions
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -6,3 +6,6 @@
|
|||
path = test/data-visual
|
||||
url = https://github.com/mapnik/test-data-visual.git
|
||||
branch = master
|
||||
[submodule "deps/mapbox/variant"]
|
||||
path = deps/mapbox/variant
|
||||
url = https://github.com/mapbox/variant.git
|
||||
|
|
|
@ -2,6 +2,13 @@
|
|||
|
||||
Mapnik runs on Linux, OS X, Windows, and BSD systems.
|
||||
|
||||
First clone mapnik from github and initialize submodules
|
||||
|
||||
```bash
|
||||
git clone https://github.com/mapnik/mapnik.git
|
||||
git submodule update --init
|
||||
```
|
||||
|
||||
To configure and build Mapnik do:
|
||||
|
||||
```bash
|
||||
|
@ -35,7 +42,6 @@ NOTE: the above will not work on windows, rather see https://github.com/mapnik/m
|
|||
|
||||
Then to run the tests locally (without needing to install):
|
||||
|
||||
git submodule update --init
|
||||
make test
|
||||
|
||||
Install like:
|
||||
|
|
|
@ -8,7 +8,9 @@ environment:
|
|||
|
||||
os: Visual Studio 2015
|
||||
|
||||
shallow_clone: true
|
||||
#shallow_clone: true
|
||||
# limit clone to latest 5 commits
|
||||
clone_depth: 5
|
||||
|
||||
install:
|
||||
- scripts\build-appveyor.bat
|
||||
|
|
1
deps/mapbox/variant
vendored
Submodule
1
deps/mapbox/variant
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 861faa8125ae7c2d9e41e33b3d5d97a17213c415
|
11
deps/mapnik/build.py
vendored
11
deps/mapnik/build.py
vendored
|
@ -4,14 +4,15 @@ from glob import glob
|
|||
Import('env')
|
||||
|
||||
subdirs = {
|
||||
'sparsehash':'sparsehash',
|
||||
'sparsehash/internal':'sparsehash/internal',
|
||||
'../agg/include':'agg',
|
||||
'./sparsehash':{'dir':'sparsehash','glob':'*'},
|
||||
'./sparsehash/internal':{'dir':'sparsehash/internal','glob':'*'},
|
||||
'../agg/include':{'dir':'agg','glob':'agg*'},
|
||||
'../mapbox':{'dir':'mapbox/variant','glob':'*/*.hpp'}
|
||||
}
|
||||
|
||||
if 'install' in COMMAND_LINE_TARGETS:
|
||||
for k,v in subdirs.items():
|
||||
pathdir = os.path.join(k,'*')
|
||||
pathdir = os.path.join(k,v['glob'])
|
||||
includes = glob(pathdir)
|
||||
inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/'+v)
|
||||
inc_target = os.path.normpath(env['INSTALL_PREFIX']+'/include/mapnik/'+v['dir'])
|
||||
env.Alias(target='install', source=env.Install(inc_target, includes))
|
||||
|
|
|
@ -172,8 +172,7 @@ template <typename charT, typename traits>
|
|||
std::basic_ostream<charT, traits> &
|
||||
operator << ( std::basic_ostream<charT, traits> & s, mapnik::color const& c )
|
||||
{
|
||||
std::string hex_string( c.to_string() );
|
||||
s << hex_string;
|
||||
s << c.to_string();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,6 +55,7 @@ private:
|
|||
mapnik::layer_descriptor desc_;
|
||||
datasource::datasource_t type_;
|
||||
bool bbox_check_;
|
||||
bool type_set_;
|
||||
mutable box2d<double> extent_;
|
||||
mutable bool dirty_extent_ = true;
|
||||
};
|
||||
|
|
|
@ -1,150 +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_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
#define MAPNIK_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
template <typename T>
|
||||
class recursive_wrapper
|
||||
{
|
||||
public:
|
||||
using type = T;
|
||||
private:
|
||||
|
||||
T* p_;
|
||||
|
||||
public:
|
||||
|
||||
~recursive_wrapper();
|
||||
recursive_wrapper();
|
||||
|
||||
recursive_wrapper(recursive_wrapper const& operand);
|
||||
recursive_wrapper(T const& operand);
|
||||
recursive_wrapper(recursive_wrapper&& operand);
|
||||
recursive_wrapper(T&& operand);
|
||||
|
||||
private:
|
||||
|
||||
void assign(const T& rhs);
|
||||
|
||||
public:
|
||||
|
||||
inline recursive_wrapper& operator=(recursive_wrapper const& rhs)
|
||||
{
|
||||
assign( rhs.get() );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline recursive_wrapper& operator=(T const& rhs)
|
||||
{
|
||||
assign( rhs );
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void swap(recursive_wrapper& operand) noexcept
|
||||
{
|
||||
T* temp = operand.p_;
|
||||
operand.p_ = p_;
|
||||
p_ = temp;
|
||||
}
|
||||
|
||||
|
||||
recursive_wrapper& operator=(recursive_wrapper&& rhs) noexcept
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
recursive_wrapper& operator=(T&& rhs)
|
||||
{
|
||||
get() = std::move(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
|
||||
T& get() { return *get_pointer(); }
|
||||
const T& get() const { return *get_pointer(); }
|
||||
T* get_pointer() { return p_; }
|
||||
const T* get_pointer() const { return p_; }
|
||||
operator T const&() const { return this->get(); }
|
||||
operator T&() { return this->get(); }
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::~recursive_wrapper()
|
||||
{
|
||||
delete p_;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper()
|
||||
: p_(new T)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper const& operand)
|
||||
: p_(new T( operand.get() ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T const& operand)
|
||||
: p_(new T(operand))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(recursive_wrapper&& operand)
|
||||
: p_(operand.p_)
|
||||
{
|
||||
operand.p_ = nullptr;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
recursive_wrapper<T>::recursive_wrapper(T&& operand)
|
||||
: p_(new T( std::move(operand) ))
|
||||
{
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void recursive_wrapper<T>::assign(const T& rhs)
|
||||
{
|
||||
this->get() = rhs;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline void swap(recursive_wrapper<T>& lhs, recursive_wrapper<T>& rhs) noexcept
|
||||
{
|
||||
lhs.swap(rhs);
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
#endif // MAPNIK_UTIL_VARIANT_RECURSIVE_WRAPPER_HPP
|
|
@ -24,854 +24,27 @@
|
|||
#define MAPNIK_UTIL_VARIANT_HPP
|
||||
|
||||
#include <mapnik/config.hpp>
|
||||
|
||||
#include <utility> // swap
|
||||
#include <typeinfo>
|
||||
#include <type_traits>
|
||||
#include <stdexcept> // runtime_error
|
||||
#include <new> // operator new
|
||||
#include <cstddef> // size_t
|
||||
#include <iosfwd>
|
||||
#include <string>
|
||||
|
||||
#include "recursive_wrapper.hpp"
|
||||
|
||||
#include <boost/mpl/vector.hpp> // spirit support
|
||||
|
||||
#ifdef _MSC_VER
|
||||
// http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx
|
||||
#ifdef NDEBUG
|
||||
#define VARIANT_INLINE __forceinline
|
||||
#else
|
||||
#define VARIANT_INLINE __declspec(noinline)
|
||||
#endif
|
||||
#else
|
||||
#ifdef NDEBUG
|
||||
#define VARIANT_INLINE inline __attribute__((always_inline))
|
||||
#else
|
||||
#define VARIANT_INLINE __attribute__((noinline))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define VARIANT_MAJOR_VERSION 0
|
||||
#define VARIANT_MINOR_VERSION 1
|
||||
#define VARIANT_PATCH_VERSION 0
|
||||
|
||||
// translates to 100
|
||||
#define VARIANT_VERSION (VARIANT_MAJOR_VERSION*100000) + (VARIANT_MINOR_VERSION*100) + (VARIANT_PATCH_VERSION)
|
||||
#include <mapbox/variant/variant.hpp>
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
|
||||
// static visitor
|
||||
template <typename R = void>
|
||||
struct static_visitor
|
||||
{
|
||||
using result_type = R;
|
||||
protected:
|
||||
static_visitor() {}
|
||||
~static_visitor() {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
static constexpr std::size_t invalid_value = std::size_t(-1);
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct direct_type;
|
||||
|
||||
template <typename T, typename First, typename...Types>
|
||||
struct direct_type<T, First, Types...>
|
||||
{
|
||||
static constexpr std::size_t index = std::is_same<T, First>::value
|
||||
? sizeof...(Types) : direct_type<T, Types...>::index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct direct_type<T>
|
||||
{
|
||||
static constexpr std::size_t index = invalid_value;
|
||||
};
|
||||
using recursive_wrapper = typename mapbox::util::recursive_wrapper<T>;
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct convertible_type;
|
||||
|
||||
template <typename T, typename First, typename...Types>
|
||||
struct convertible_type<T, First, Types...>
|
||||
{
|
||||
static constexpr std::size_t index = std::is_convertible<T, First>::value
|
||||
? sizeof...(Types) : convertible_type<T, Types...>::index;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct convertible_type<T>
|
||||
{
|
||||
static constexpr std::size_t index = invalid_value;
|
||||
};
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct value_traits
|
||||
{
|
||||
static constexpr std::size_t direct_index = direct_type<T, Types...>::index;
|
||||
static constexpr std::size_t index =
|
||||
(direct_index == invalid_value) ? convertible_type<T, Types...>::index : direct_index;
|
||||
};
|
||||
|
||||
// check if T is in Types...
|
||||
template <typename T, typename...Types>
|
||||
struct has_type;
|
||||
|
||||
template <typename T, typename First, typename... Types>
|
||||
struct has_type<T, First, Types...>
|
||||
{
|
||||
static constexpr bool value = std::is_same<T, First>::value
|
||||
|| has_type<T, Types...>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct has_type<T> : std::false_type {};
|
||||
//
|
||||
|
||||
template <typename T, typename...Types>
|
||||
struct is_valid_type;
|
||||
|
||||
template <typename T, typename First, typename... Types>
|
||||
struct is_valid_type<T, First, Types...>
|
||||
{
|
||||
static constexpr bool value = std::is_convertible<T, First>::value
|
||||
|| is_valid_type<T, Types...>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_valid_type<T> : std::false_type {};
|
||||
|
||||
template <std::size_t N, typename ... Types>
|
||||
struct select_type
|
||||
{
|
||||
static_assert(N < sizeof...(Types), "index out of bounds");
|
||||
};
|
||||
|
||||
template <std::size_t N, typename T, typename ... Types>
|
||||
struct select_type<N, T, Types...>
|
||||
{
|
||||
using type = typename select_type<N - 1, Types...>::type;
|
||||
};
|
||||
|
||||
template <typename T, typename ... Types>
|
||||
struct select_type<0, T, Types...>
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
|
||||
template <typename T, typename R = void>
|
||||
struct enable_if_type { using type = R; };
|
||||
|
||||
template <typename F, typename V, typename Enable = void>
|
||||
struct result_of_unary_visit
|
||||
{
|
||||
using type = typename std::result_of<F(V&)>::type;
|
||||
};
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_unary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
template <typename F, typename V, class Enable = void>
|
||||
struct result_of_binary_visit
|
||||
{
|
||||
using type = typename std::result_of<F(V&,V&)>::type;
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V>
|
||||
struct result_of_binary_visit<F, V, typename enable_if_type<typename F::result_type>::type >
|
||||
{
|
||||
using type = typename F::result_type;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
||||
template <std::size_t arg1, std::size_t ... others>
|
||||
struct static_max;
|
||||
|
||||
template <std::size_t arg>
|
||||
struct static_max<arg>
|
||||
{
|
||||
static const std::size_t value = arg;
|
||||
};
|
||||
|
||||
template <std::size_t arg1, std::size_t arg2, std::size_t ... others>
|
||||
struct static_max<arg1, arg2, others...>
|
||||
{
|
||||
static const std::size_t value = arg1 >= arg2 ? static_max<arg1, others...>::value :
|
||||
static_max<arg2, others...>::value;
|
||||
};
|
||||
|
||||
template<typename... Types>
|
||||
struct variant_helper;
|
||||
|
||||
template<typename T, typename... Types>
|
||||
struct variant_helper<T, Types...>
|
||||
{
|
||||
VARIANT_INLINE static void destroy(const std::size_t id, void * data)
|
||||
{
|
||||
if (id == sizeof...(Types))
|
||||
{
|
||||
reinterpret_cast<T*>(data)->~T();
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::destroy(id, data);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static void move(const std::size_t old_id, void * old_value, void * new_value)
|
||||
{
|
||||
if (old_id == sizeof...(Types))
|
||||
{
|
||||
new (new_value) T(std::move(*reinterpret_cast<T*>(old_value)));
|
||||
//std::memcpy(new_value, old_value, sizeof(T));
|
||||
// ^^ DANGER: this should only be considered for relocatable types e.g built-in types
|
||||
// Also, I don't see any measurable performance benefit just yet
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::move(old_id, old_value, new_value);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static void copy(const std::size_t old_id, const void * old_value, void * new_value)
|
||||
{
|
||||
if (old_id == sizeof...(Types))
|
||||
{
|
||||
new (new_value) T(*reinterpret_cast<const T*>(old_value));
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::copy(old_id, old_value, new_value);
|
||||
}
|
||||
}
|
||||
VARIANT_INLINE static void direct_swap(const std::size_t id, void * lhs, void * rhs)
|
||||
{
|
||||
using std::swap; //enable ADL
|
||||
if (id == sizeof...(Types))
|
||||
{
|
||||
// both lhs and rhs hold T
|
||||
swap(*reinterpret_cast<T*>(lhs), *reinterpret_cast<T*>(rhs));
|
||||
}
|
||||
else
|
||||
{
|
||||
variant_helper<Types...>::direct_swap(id, lhs, rhs);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<> struct variant_helper<>
|
||||
{
|
||||
VARIANT_INLINE static void destroy(const std::size_t, void *) {}
|
||||
VARIANT_INLINE static void move(const std::size_t, void *, void *) {}
|
||||
VARIANT_INLINE static void copy(const std::size_t, const void *, void *) {}
|
||||
VARIANT_INLINE static void direct_swap(const std::size_t, void *, void *) {}
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper
|
||||
{
|
||||
static T const& apply_const(T const& obj) {return obj;}
|
||||
static T& apply(T & obj) {return obj;}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper<recursive_wrapper<T>>
|
||||
{
|
||||
static auto apply_const(recursive_wrapper<T> const& obj)
|
||||
-> typename recursive_wrapper<T>::type const&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
static auto apply(recursive_wrapper<T> & obj)
|
||||
-> typename recursive_wrapper<T>::type&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct unwrapper<std::reference_wrapper<T>>
|
||||
{
|
||||
static auto apply_const(std::reference_wrapper<T> const& obj)
|
||||
-> typename std::reference_wrapper<T>::type const&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
static auto apply(std::reference_wrapper<T> & obj)
|
||||
-> typename std::reference_wrapper<T>::type&
|
||||
{
|
||||
return obj.get();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename V, typename R, typename...Types>
|
||||
struct dispatcher;
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct dispatcher<F, V, R, T, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return f(unwrapper<T>::apply_const(v. template get<T>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dispatcher<F, V, R, Types...>::apply_const(v, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & v, F f)
|
||||
{
|
||||
if (v.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return f(unwrapper<T>::apply(v. template get<T>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return dispatcher<F, V, R, Types...>::apply(v, f);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R>
|
||||
struct dispatcher<F, V, R>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, F)
|
||||
{
|
||||
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, F)
|
||||
{
|
||||
throw std::runtime_error(std::string("unary dispatch: FAIL ") + typeid(V).name());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher_rhs;
|
||||
|
||||
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_rhs<F, V, R, T0, T1, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T0>::apply_const(lhs. template get<T0>()),
|
||||
unwrapper<T1>::apply_const(rhs. template get<T1>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
|
||||
{
|
||||
if (rhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T0>::apply(lhs. template get<T0>()),
|
||||
unwrapper<T1>::apply(rhs. template get<T1>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R, typename T>
|
||||
struct binary_dispatcher_rhs<F, V, R, T>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher_lhs;
|
||||
|
||||
template <typename F, typename V, typename R, typename T0, typename T1, typename...Types>
|
||||
struct binary_dispatcher_lhs<F, V, R, T0, T1, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& lhs, V const& rhs, F f)
|
||||
{
|
||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T1>::apply_const(lhs. template get<T1>()),
|
||||
unwrapper<T0>::apply_const(rhs. template get<T0>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply_const(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & lhs, V & rhs, F f)
|
||||
{
|
||||
if (lhs.get_type_index() == sizeof...(Types)) // call binary functor
|
||||
{
|
||||
return f(unwrapper<T1>::apply(lhs. template get<T1>()),
|
||||
unwrapper<T0>::apply(rhs. template get<T0>()));
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T0, Types...>::apply(lhs, rhs, f);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R, typename T>
|
||||
struct binary_dispatcher_lhs<F, V, R, T>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
template <typename F, typename V, typename R, typename...Types>
|
||||
struct binary_dispatcher;
|
||||
|
||||
template <typename F, typename V, typename R, typename T, typename...Types>
|
||||
struct binary_dispatcher<F, V, R, T, Types...>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const& v0, V const& v1, F f)
|
||||
{
|
||||
if (v0.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
if (v0.get_type_index() == v1.get_type_index())
|
||||
{
|
||||
return f(unwrapper<T>::apply_const(v0. template get<T>()),
|
||||
unwrapper<T>::apply_const(v1. template get<T>())); // call binary functor
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
}
|
||||
else if (v1.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
return binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V & v0, V & v1, F f)
|
||||
{
|
||||
if (v0.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
if (v0.get_type_index() == v1.get_type_index())
|
||||
{
|
||||
return f(unwrapper<T>::apply(v0. template get<T>()),
|
||||
unwrapper<T>::apply(v1. template get<T>())); // call binary functor
|
||||
}
|
||||
else
|
||||
{
|
||||
return binary_dispatcher_rhs<F, V, R, T, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
}
|
||||
else if (v1.get_type_index() == sizeof...(Types))
|
||||
{
|
||||
return binary_dispatcher_lhs<F, V, R, T, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
return binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename F, typename V, typename R>
|
||||
struct binary_dispatcher<F, V, R>
|
||||
{
|
||||
using result_type = R;
|
||||
VARIANT_INLINE static result_type apply_const(V const&, V const&, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
|
||||
VARIANT_INLINE static result_type apply(V &, V &, F)
|
||||
{
|
||||
throw std::runtime_error("binary dispatch: FAIL");
|
||||
}
|
||||
};
|
||||
|
||||
// comparator functors
|
||||
struct equal_comp
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& lhs, T const& rhs) const
|
||||
{
|
||||
return lhs == rhs;
|
||||
}
|
||||
};
|
||||
|
||||
struct less_comp
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& lhs, T const& rhs) const
|
||||
{
|
||||
return lhs < rhs;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename Variant, typename Comp>
|
||||
class comparer
|
||||
class variant : public mapbox::util::variant<Types...>
|
||||
{
|
||||
public:
|
||||
explicit comparer(Variant const& lhs) noexcept
|
||||
: lhs_(lhs) {}
|
||||
comparer& operator=(comparer const&) = delete;
|
||||
// visitor
|
||||
template<typename T>
|
||||
bool operator()(T const& rhs_content) const
|
||||
{
|
||||
T const& lhs_content = lhs_.template get<T>();
|
||||
return Comp()(lhs_content, rhs_content);
|
||||
}
|
||||
private:
|
||||
Variant const& lhs_;
|
||||
};
|
||||
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct no_init {};
|
||||
|
||||
template<typename... Types>
|
||||
class variant
|
||||
{
|
||||
private:
|
||||
|
||||
static const std::size_t data_size = static_max<sizeof(Types)...>::value;
|
||||
static const std::size_t data_align = static_max<alignof(Types)...>::value;
|
||||
|
||||
using data_type = typename std::aligned_storage<data_size, data_align>::type;
|
||||
using helper_type = variant_helper<Types...>;
|
||||
|
||||
std::size_t type_index;
|
||||
data_type data;
|
||||
|
||||
public:
|
||||
|
||||
// tell spirit that this is an adapted variant
|
||||
struct adapted_variant_tag;
|
||||
using types = boost::mpl::vector<Types...>;
|
||||
|
||||
VARIANT_INLINE variant()
|
||||
: type_index(sizeof...(Types) - 1)
|
||||
{
|
||||
new (&data) typename detail::select_type<0, Types...>::type();
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(no_init)
|
||||
: type_index(detail::invalid_value) {}
|
||||
|
||||
// http://isocpp.org/blog/2012/11/universal-references-in-c11-scott-meyers
|
||||
template <typename T, class = typename std::enable_if<
|
||||
detail::is_valid_type<typename std::remove_reference<T>::type, Types...>::value>::type>
|
||||
VARIANT_INLINE variant(T && val) noexcept
|
||||
: type_index(detail::value_traits<typename std::remove_reference<T>::type, Types...>::index)
|
||||
{
|
||||
constexpr std::size_t index = sizeof...(Types) - detail::value_traits<typename std::remove_reference<T>::type, Types...>::index - 1;
|
||||
using target_type = typename detail::select_type<index, Types...>::type;
|
||||
new (&data) target_type(std::forward<T>(val)); // nothrow
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(variant<Types...> const& old)
|
||||
: type_index(old.type_index)
|
||||
{
|
||||
helper_type::copy(old.type_index, &old.data, &data);
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant(variant<Types...>&& old) noexcept
|
||||
: type_index(old.type_index)
|
||||
{
|
||||
helper_type::move(old.type_index, &old.data, &data);
|
||||
}
|
||||
|
||||
private:
|
||||
VARIANT_INLINE void copy_assign(variant<Types...> const& rhs)
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
type_index = detail::invalid_value;
|
||||
helper_type::copy(rhs.type_index, &rhs.data, &data);
|
||||
type_index = rhs.type_index;
|
||||
}
|
||||
|
||||
VARIANT_INLINE void move_assign(variant<Types...> && rhs)
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
type_index = detail::invalid_value;
|
||||
helper_type::move(rhs.type_index, &rhs.data, &data);
|
||||
type_index = rhs.type_index;
|
||||
}
|
||||
|
||||
public:
|
||||
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> && other)
|
||||
{
|
||||
move_assign(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
VARIANT_INLINE variant<Types...>& operator=(variant<Types...> const& other)
|
||||
{
|
||||
copy_assign(other);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// conversions
|
||||
// move-assign
|
||||
template <typename T>
|
||||
VARIANT_INLINE variant<Types...>& operator=(T && rhs) noexcept
|
||||
{
|
||||
variant<Types...> temp(std::forward<T>(rhs));
|
||||
move_assign(std::move(temp));
|
||||
return *this;
|
||||
}
|
||||
|
||||
// copy-assign
|
||||
template <typename T>
|
||||
VARIANT_INLINE variant<Types...>& operator=(T const& rhs)
|
||||
{
|
||||
variant<Types...> temp(rhs);
|
||||
copy_assign(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
VARIANT_INLINE bool is() const
|
||||
{
|
||||
static_assert(detail::has_type<T, Types...>::value, "invalid type in T in `is<T>()` for this variant");
|
||||
return (type_index == detail::direct_type<T, Types...>::index);
|
||||
}
|
||||
|
||||
VARIANT_INLINE bool valid() const
|
||||
{
|
||||
return (type_index != detail::invalid_value);
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
VARIANT_INLINE void set(Args&&... args)
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
new (&data) T(std::forward<Args>(args)...);
|
||||
type_index = detail::direct_type<T, Types...>::index;
|
||||
}
|
||||
|
||||
// get<T>()
|
||||
template<typename T, typename std::enable_if<
|
||||
(detail::direct_type<T, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<T, Types...>::index)
|
||||
{
|
||||
return *reinterpret_cast<T*>(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<T, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<T, Types...>::index)
|
||||
{
|
||||
return *reinterpret_cast<T const*>(&data);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
// get<T>() - T stored as recursive_wrapper<T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T>*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,typename std::enable_if<
|
||||
(detail::direct_type<recursive_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<recursive_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<recursive_wrapper<T> const*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
// get<T>() - T stored as std::reference_wrapper<T>
|
||||
template <typename T, typename std::enable_if<
|
||||
(detail::direct_type<std::reference_wrapper<T>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T& get()
|
||||
{
|
||||
if (type_index == detail::direct_type<std::reference_wrapper<T>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<std::reference_wrapper<T>*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T,typename std::enable_if<
|
||||
(detail::direct_type<std::reference_wrapper<T const>, Types...>::index != detail::invalid_value)
|
||||
>::type* = nullptr>
|
||||
VARIANT_INLINE T const& get() const
|
||||
{
|
||||
if (type_index == detail::direct_type<std::reference_wrapper<T const>, Types...>::index)
|
||||
{
|
||||
return (*reinterpret_cast<std::reference_wrapper<T const> const*>(&data)).get();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw std::runtime_error("in get<T>()");
|
||||
}
|
||||
}
|
||||
|
||||
VARIANT_INLINE std::size_t get_type_index() const
|
||||
{
|
||||
return type_index;
|
||||
}
|
||||
|
||||
VARIANT_INLINE int which() const noexcept
|
||||
{
|
||||
return static_cast<int>(sizeof...(Types) - type_index - 1);
|
||||
}
|
||||
// visitor
|
||||
// unary
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static visit(V const& v, F f)
|
||||
-> decltype(detail::dispatcher<F, V,
|
||||
typename detail::result_of_unary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v, f))
|
||||
{
|
||||
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::dispatcher<F, V, R, Types...>::apply_const(v, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static visit(V & v, F f)
|
||||
-> decltype(detail::dispatcher<F, V,
|
||||
typename detail::result_of_unary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v, f))
|
||||
{
|
||||
using R = typename detail::result_of_unary_visit<F, typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::dispatcher<F, V, R, Types...>::apply(v, f);
|
||||
}
|
||||
|
||||
// binary
|
||||
// const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static binary_visit(V const& v0, V const& v1, F f)
|
||||
-> decltype(detail::binary_dispatcher<F, V,
|
||||
typename detail::result_of_binary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply_const(v0, v1, f))
|
||||
{
|
||||
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::binary_dispatcher<F, V, R, Types...>::apply_const(v0, v1, f);
|
||||
}
|
||||
// non-const
|
||||
template <typename F, typename V>
|
||||
auto VARIANT_INLINE
|
||||
static binary_visit(V& v0, V& v1, F f)
|
||||
-> decltype(detail::binary_dispatcher<F, V,
|
||||
typename detail::result_of_binary_visit<F,
|
||||
typename detail::select_type<0, Types...>::type>::type, Types...>::apply(v0, v1, f))
|
||||
{
|
||||
using R = typename detail::result_of_binary_visit<F,typename detail::select_type<0, Types...>::type>::type;
|
||||
return detail::binary_dispatcher<F, V, R, Types...>::apply(v0, v1, f);
|
||||
}
|
||||
|
||||
~variant() noexcept
|
||||
{
|
||||
helper_type::destroy(type_index, &data);
|
||||
}
|
||||
|
||||
// comparison operators
|
||||
// equality
|
||||
VARIANT_INLINE bool operator==(variant const& rhs) const
|
||||
{
|
||||
if (this->get_type_index() != rhs.get_type_index())
|
||||
return false;
|
||||
detail::comparer<variant, detail::equal_comp> visitor(*this);
|
||||
return visit(rhs, visitor);
|
||||
}
|
||||
// less than
|
||||
VARIANT_INLINE bool operator<(variant const& rhs) const
|
||||
{
|
||||
if (this->get_type_index() != rhs.get_type_index())
|
||||
{
|
||||
return this->get_type_index() < rhs.get_type_index();
|
||||
// ^^ borrowed from boost::variant
|
||||
}
|
||||
detail::comparer<variant, detail::less_comp> visitor(*this);
|
||||
return visit(rhs, visitor);
|
||||
}
|
||||
// inherit ctor's
|
||||
using mapbox::util::variant<Types...>::variant;
|
||||
};
|
||||
|
||||
// unary visitor interface
|
||||
|
||||
// const
|
||||
template <typename V, typename F>
|
||||
auto VARIANT_INLINE static apply_visitor(F f, V const& v) -> decltype(V::visit(v, f))
|
||||
|
@ -900,13 +73,13 @@ auto VARIANT_INLINE static apply_visitor(F f, V & v0, V & v1) -> decltype(V::bin
|
|||
}
|
||||
|
||||
// getter interface
|
||||
template<typename ResultType, typename T>
|
||||
template <typename ResultType, typename T>
|
||||
ResultType & get(T & var)
|
||||
{
|
||||
return var.template get<ResultType>();
|
||||
}
|
||||
|
||||
template<typename ResultType, typename T>
|
||||
template <typename ResultType, typename T>
|
||||
ResultType const& get(T const& var)
|
||||
{
|
||||
return var.template get<ResultType>();
|
||||
|
|
|
@ -65,7 +65,7 @@ VARIANT_INLINE std::basic_ostream<charT, traits>&
|
|||
operator<< (std::basic_ostream<charT, traits>& out, variant<Types...> const& rhs)
|
||||
{
|
||||
detail::printer<std::basic_ostream<charT, traits>> visitor(out);
|
||||
apply_visitor(visitor, rhs);
|
||||
mapnik::util::apply_visitor(visitor, rhs);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define MAPNIK_WKB_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/geometry.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
|
||||
|
|
|
@ -28,6 +28,10 @@ ECHO ========
|
|||
SET PATH=C:\Python27;%PATH%
|
||||
SET PATH=C:\Program Files\7-Zip;%PATH%
|
||||
|
||||
::update submodule variant
|
||||
git submodule update --init deps/mapbox/variant
|
||||
IF %ERRORLEVEL% NEQ 0 GOTO ERROR
|
||||
|
||||
::cloning mapnik-gyp
|
||||
if EXIST mapnik-gyp ECHO mapnik-gyp already cloned && GOTO MAPNIK_GYP_ALREADY_HERE
|
||||
CALL git clone https://github.com/mapnik/mapnik-gyp.git
|
||||
|
|
|
@ -73,7 +73,8 @@ memory_datasource::memory_datasource(parameters const& params)
|
|||
desc_(memory_datasource::name(),
|
||||
*params.get<std::string>("encoding","utf-8")),
|
||||
type_(datasource::Vector),
|
||||
bbox_check_(*params.get<boolean_type>("bbox_check", true)) {}
|
||||
bbox_check_(*params.get<boolean_type>("bbox_check", true)),
|
||||
type_set_(false) {}
|
||||
|
||||
memory_datasource::~memory_datasource() {}
|
||||
|
||||
|
@ -81,6 +82,30 @@ void memory_datasource::push(feature_ptr feature)
|
|||
{
|
||||
// TODO - collect attribute descriptors?
|
||||
//desc_.add_descriptor(attribute_descriptor(fld_name,mapnik::Integer));
|
||||
if (feature->get_raster())
|
||||
{
|
||||
// if a feature has a raster_ptr set it must be of raster type.
|
||||
if (!type_set_)
|
||||
{
|
||||
type_ = datasource::Raster;
|
||||
type_set_ = true;
|
||||
}
|
||||
else if (type_ == datasource::Vector)
|
||||
{
|
||||
throw std::runtime_error("Can not add a raster feature to a memory datasource that contains vectors");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!type_set_)
|
||||
{
|
||||
type_set_ = true;
|
||||
}
|
||||
else if (type_ == datasource::Raster)
|
||||
{
|
||||
throw std::runtime_error("Can not add a vector feature to a memory datasource that contains rasters");
|
||||
}
|
||||
}
|
||||
features_.push_back(feature);
|
||||
dirty_extent_ = true;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,6 @@
|
|||
#include <mapnik/group/group_symbolizer_properties.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/util/variant_io.hpp>
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
|
|
@ -124,7 +124,7 @@ template <typename T>
|
|||
double parse_double(T & error_messages, const char* str)
|
||||
{
|
||||
using namespace boost::spirit::qi;
|
||||
qi::double_type double_;
|
||||
double_type double_;
|
||||
double val = 0.0;
|
||||
if (!parse(str, str + std::strlen(str),double_,val))
|
||||
{
|
||||
|
@ -133,24 +133,33 @@ double parse_double(T & error_messages, const char* str)
|
|||
return val;
|
||||
}
|
||||
|
||||
|
||||
// parse a double that might end with a %
|
||||
// if it does then set the ref bool true and divide the result by 100
|
||||
|
||||
template <typename T>
|
||||
double parse_double_optional_percent(T & error_messages, const char* str, bool &percent)
|
||||
// https://www.w3.org/TR/SVG/coords.html#Units
|
||||
template <typename T, int DPI = 90>
|
||||
double parse_svg_value(T & error_messages, const char* str, bool & percent)
|
||||
{
|
||||
using namespace boost::spirit::qi;
|
||||
using skip_type = boost::spirit::ascii::space_type;
|
||||
using boost::phoenix::ref;
|
||||
qi::_1_type _1;
|
||||
qi::double_type double_;
|
||||
qi::char_type char_;
|
||||
|
||||
double_type double_;
|
||||
char_type char_;
|
||||
_1_type _1;
|
||||
double val = 0.0;
|
||||
if (!parse(str, str + std::strlen(str),double_[ref(val)=_1, ref(percent) = false]
|
||||
>> -char_('%')[ref(val) /= 100.0, ref(percent) = true]))
|
||||
symbols<char, double> units;
|
||||
units.add
|
||||
("pt", DPI/72.0)
|
||||
("pc", DPI/6.0)
|
||||
("mm", DPI/25.4)
|
||||
("cm", DPI/2.54)
|
||||
("in", (double)DPI)
|
||||
;
|
||||
if (!phrase_parse(str, str + std::strlen(str),
|
||||
double_[ref(val) = _1, ref(percent) = false]
|
||||
> - (units[ ref(val) *= _1]
|
||||
|
|
||||
char_('%')[ref(val) *= 0.01, ref(percent) = true]),
|
||||
skip_type()))
|
||||
{
|
||||
error_messages.emplace_back("Failed to parse double (optional %) from " + std::string(str));
|
||||
error_messages.emplace_back("Failed to parse SVG value: \"" + std::string(str) + "\"");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
@ -160,9 +169,9 @@ bool parse_double_list(T & error_messages, const char* str, double* list)
|
|||
{
|
||||
using namespace boost::spirit::qi;
|
||||
using boost::phoenix::ref;
|
||||
qi::_1_type _1;
|
||||
qi::double_type double_;
|
||||
qi::lit_type lit;
|
||||
_1_type _1;
|
||||
double_type double_;
|
||||
lit_type lit;
|
||||
using skip_type = boost::spirit::ascii::space_type;
|
||||
|
||||
if (!phrase_parse(str, str + std::strlen(str),
|
||||
|
@ -412,7 +421,8 @@ void parse_attr(svg_parser & parser, char const* name, char const* value )
|
|||
}
|
||||
else if (std::strcmp(name, "stroke-width") == 0)
|
||||
{
|
||||
parser.path_.stroke_width(parse_double(parser.error_messages_, value));
|
||||
bool percent;
|
||||
parser.path_.stroke_width(parse_svg_value(parser.error_messages_, value, percent));
|
||||
}
|
||||
else if (std::strcmp(name, "stroke-opacity") == 0)
|
||||
{
|
||||
|
@ -468,7 +478,6 @@ void parse_attr(svg_parser & parser, char const* name, char const* value )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void parse_attr(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||
{
|
||||
for (rapidxml::xml_attribute<char> const* attr = node->first_attribute();
|
||||
|
@ -506,12 +515,12 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
|||
auto const* width_attr = node->first_attribute("width");
|
||||
if (width_attr)
|
||||
{
|
||||
width = parse_double_optional_percent(parser.error_messages_, width_attr->value(), has_percent_width);
|
||||
width = parse_svg_value(parser.error_messages_, width_attr->value(), has_percent_width);
|
||||
}
|
||||
auto const* height_attr = node->first_attribute("height");
|
||||
if (height_attr)
|
||||
{
|
||||
height = parse_double_optional_percent(parser.error_messages_, height_attr->value(), has_percent_height);
|
||||
height = parse_svg_value(parser.error_messages_, height_attr->value(), has_percent_height);
|
||||
}
|
||||
auto const* viewbox_attr = node->first_attribute("viewBox");
|
||||
if (viewbox_attr)
|
||||
|
@ -602,18 +611,18 @@ void parse_line(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
|||
double y1 = 0.0;
|
||||
double x2 = 0.0;
|
||||
double y2 = 0.0;
|
||||
|
||||
bool percent;
|
||||
auto const* x1_attr = node->first_attribute("x1");
|
||||
if (x1_attr) x1 = parse_double(parser.error_messages_, x1_attr->value());
|
||||
if (x1_attr) x1 = parse_svg_value(parser.error_messages_, x1_attr->value(), percent);
|
||||
|
||||
auto const* y1_attr = node->first_attribute("y1");
|
||||
if (y1_attr) y1 = parse_double(parser.error_messages_, y1_attr->value());
|
||||
if (y1_attr) y1 = parse_svg_value(parser.error_messages_, y1_attr->value(), percent);
|
||||
|
||||
auto const* x2_attr = node->first_attribute("x2");
|
||||
if (x2_attr) x2 = parse_double(parser.error_messages_, x2_attr->value());
|
||||
if (x2_attr) x2 = parse_svg_value(parser.error_messages_, x2_attr->value(), percent);
|
||||
|
||||
auto const* y2_attr = node->first_attribute("y2");
|
||||
if (y2_attr) y2 = parse_double(parser.error_messages_, y2_attr->value());
|
||||
if (y2_attr) y2 = parse_svg_value(parser.error_messages_, y2_attr->value(), percent);
|
||||
|
||||
parser.path_.begin_path();
|
||||
parser.path_.move_to(x1, y1);
|
||||
|
@ -626,23 +635,23 @@ void parse_circle(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
|||
double cx = 0.0;
|
||||
double cy = 0.0;
|
||||
double r = 0.0;
|
||||
|
||||
bool percent;
|
||||
auto * attr = node->first_attribute("cx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
cx = parse_double(parser.error_messages_, attr->value());
|
||||
cx = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("cy");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
cy = parse_double(parser.error_messages_, attr->value());
|
||||
cy = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("r");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
r = parse_double(parser.error_messages_, attr->value());
|
||||
r = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
parser.path_.begin_path();
|
||||
|
@ -667,29 +676,29 @@ void parse_ellipse(svg_parser & parser, rapidxml::xml_node<char> const * node)
|
|||
double cy = 0.0;
|
||||
double rx = 0.0;
|
||||
double ry = 0.0;
|
||||
|
||||
bool percent;
|
||||
auto * attr = node->first_attribute("cx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
cx = parse_double(parser.error_messages_, attr->value());
|
||||
cx = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("cy");
|
||||
if (attr)
|
||||
{
|
||||
cy = parse_double(parser.error_messages_, attr->value());
|
||||
cy = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("rx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
rx = parse_double(parser.error_messages_, attr->value());
|
||||
rx = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("ry");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
ry = parse_double(parser.error_messages_, attr->value());
|
||||
ry = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
if (rx != 0.0 && ry != 0.0)
|
||||
|
@ -722,35 +731,35 @@ void parse_rect(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
|||
double h = 0.0;
|
||||
double rx = 0.0;
|
||||
double ry = 0.0;
|
||||
|
||||
bool percent;
|
||||
auto * attr = node->first_attribute("x");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
x = parse_double(parser.error_messages_, attr->value());
|
||||
x = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("y");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
y = parse_double(parser.error_messages_, attr->value());
|
||||
y = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("width");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
w = parse_double(parser.error_messages_, attr->value());
|
||||
w = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
attr = node->first_attribute("height");
|
||||
if (attr)
|
||||
{
|
||||
h = parse_double(parser.error_messages_, attr->value());
|
||||
h = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
}
|
||||
|
||||
bool rounded = true;
|
||||
attr = node->first_attribute("rx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
rx = parse_double(parser.error_messages_, attr->value());
|
||||
rx = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
if ( rx > 0.5 * w ) rx = 0.5 * w;
|
||||
}
|
||||
else rounded = false;
|
||||
|
@ -758,7 +767,7 @@ void parse_rect(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
|||
attr = node->first_attribute("ry");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
ry = parse_double(parser.error_messages_, attr->value());
|
||||
ry = parse_svg_value(parser.error_messages_, attr->value(), percent);
|
||||
if ( ry > 0.5 * h ) ry = 0.5 * h;
|
||||
if (!rounded)
|
||||
{
|
||||
|
@ -937,19 +946,19 @@ void parse_radial_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
|
|||
auto * attr = node->first_attribute("cx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
cx = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
cx = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("cy");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
cy = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
cy = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("fx");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
fx = parse_double_optional_percent(parser.error_messages_,attr->value(), has_percent);
|
||||
fx = parse_svg_value(parser.error_messages_,attr->value(), has_percent);
|
||||
}
|
||||
else
|
||||
fx = cx;
|
||||
|
@ -957,7 +966,7 @@ void parse_radial_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
|
|||
attr = node->first_attribute("fy");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
fy = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
fy = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
else
|
||||
fy = cy;
|
||||
|
@ -965,7 +974,7 @@ void parse_radial_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
|
|||
attr = node->first_attribute("r");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
r = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
r = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
// this logic for detecting %'s will not support mixed coordinates.
|
||||
if (has_percent && parser.temporary_gradient_.second.get_units() == USER_SPACE_ON_USE)
|
||||
|
@ -994,25 +1003,25 @@ void parse_linear_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
|
|||
auto * attr = node->first_attribute("x1");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
x1 = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
x1 = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("x2");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
x2 = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
x2 = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("y1");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
y1 = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
y1 = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
|
||||
attr = node->first_attribute("y2");
|
||||
if (attr != nullptr)
|
||||
{
|
||||
y2 = parse_double_optional_percent(parser.error_messages_, attr->value(), has_percent);
|
||||
y2 = parse_svg_value(parser.error_messages_, attr->value(), has_percent);
|
||||
}
|
||||
// this logic for detecting %'s will not support mixed coordinates.
|
||||
if (has_percent && parser.temporary_gradient_.second.get_units() == USER_SPACE_ON_USE)
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 5be80ebbd596e42e45fc6dfd4cfca0cc6b814c73
|
||||
Subproject commit 2448353f8e4e142ccaae35e155503b2cb88eb344
|
|
@ -1 +1 @@
|
|||
Subproject commit af88691110b39c75f97140ab4b608b258e53ad51
|
||||
Subproject commit c2b3f12c3620dde8310315a21c0b952fd62c490a
|
|
@ -4,6 +4,7 @@
|
|||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/css_color_grammar_def.hpp>
|
||||
|
||||
#include <sstream>
|
||||
|
||||
TEST_CASE("CSS color") {
|
||||
|
||||
|
@ -221,4 +222,27 @@ TEST_CASE("CSS color") {
|
|||
CHECK( !boost::spirit::x3::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
|
||||
}
|
||||
}
|
||||
SECTION("operator<< / to_string()")
|
||||
{
|
||||
mapnik::color c("salmon");
|
||||
std::ostringstream ss;
|
||||
ss << c ;
|
||||
CHECK(ss.str() == "rgb(250,128,114)");
|
||||
c.set_alpha(127);
|
||||
ss.seekp(0);
|
||||
ss << c ;
|
||||
CHECK(ss.str() == "rgba(250,128,114,0.498)");
|
||||
}
|
||||
SECTION("premultiply/demultiply")
|
||||
{
|
||||
mapnik::color c("cornflowerblue");
|
||||
c.set_alpha(127);
|
||||
c.premultiply();
|
||||
CHECK(int(c.red()) == 50);
|
||||
CHECK(int(c.green()) == 74);
|
||||
CHECK(int(c.blue()) == 118);
|
||||
CHECK(int(c.alpha()) == 127);
|
||||
c.demultiply();
|
||||
CHECK(c == mapnik::color(100, 148, 236, 127));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <mapnik/coord.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include "agg_trans_affine.h"
|
||||
|
||||
TEST_CASE("box2d") {
|
||||
SECTION("coord init") {
|
||||
|
@ -159,4 +160,62 @@ SECTION("envelope clipping") {
|
|||
REQUIRE(e1 == e2);
|
||||
}
|
||||
|
||||
SECTION("mapnik::box2d intersects")
|
||||
{
|
||||
mapnik::box2d<double> b0(0,0,100,100);
|
||||
// another box2d
|
||||
mapnik::box2d<double> b1(100,100,200,200);
|
||||
CHECK(b0.intersects(b1));
|
||||
CHECK(b1.intersects(b0));
|
||||
mapnik::box2d<double> b2(100.001,100,200,200);
|
||||
CHECK(!b0.intersects(b2));
|
||||
CHECK(!b2.intersects(b0));
|
||||
// coord
|
||||
CHECK(b0.intersects(mapnik::coord<double,2>(100,100)));
|
||||
CHECK(!b0.intersects(mapnik::coord<double,2>(100.001,100)));
|
||||
}
|
||||
|
||||
SECTION("mapnik::box2d intersect")
|
||||
{
|
||||
mapnik::box2d<double> b0(0,0,100,100);
|
||||
mapnik::box2d<double> b1(100,100,200,200);
|
||||
CHECK(b0.intersect(b1) == mapnik::box2d<double>(100,100,100,100));
|
||||
CHECK(b1.intersect(b0) == mapnik::box2d<double>(100,100,100,100));
|
||||
mapnik::box2d<double> b2(100.001,100,200,200);
|
||||
CHECK(b0.intersect(b2) == mapnik::box2d<double>());
|
||||
CHECK(b2.intersect(b0) == mapnik::box2d<double>());
|
||||
}
|
||||
|
||||
SECTION("mapnik::box2d re_center")
|
||||
{
|
||||
mapnik::box2d<double> b(0, 0, 100, 100);
|
||||
b.re_center(0, 0);
|
||||
CHECK(b == mapnik::box2d<double>(-50, -50, 50, 50));
|
||||
b.re_center(mapnik::coord2d(50,50));
|
||||
CHECK(b == mapnik::box2d<double>(0, 0, 100, 100));
|
||||
}
|
||||
|
||||
SECTION("mapnik::box2d operator+=")
|
||||
{
|
||||
mapnik::box2d<double> b(0, 0, 50, 50);
|
||||
b += mapnik::box2d<double>(100, 100, 200, 200);
|
||||
CHECK(b == mapnik::box2d<double>(0, 0, 200, 200));
|
||||
b += 100;
|
||||
CHECK(b == mapnik::box2d<double>(-100, -100, 300, 300));
|
||||
}
|
||||
|
||||
SECTION("mapnik::box2d operator*= operator=/ ")
|
||||
{
|
||||
mapnik::box2d<double> b(0, 0, 100, 100);
|
||||
b *= 2.0;
|
||||
CHECK(b == mapnik::box2d<double>(-50, -50, 150, 150));
|
||||
b /= 2.0;
|
||||
CHECK(b == mapnik::box2d<double>(0, 0, 100, 100));
|
||||
|
||||
agg::trans_affine tr;
|
||||
tr.translate(-50,-50);
|
||||
tr.scale(2.0);
|
||||
b *= tr;
|
||||
CHECK(b == mapnik::box2d<double>(-100, -100, 100, 100));
|
||||
}
|
||||
} // TEST_CASE
|
||||
|
|
|
@ -36,7 +36,7 @@ std::string vector_to_string(T const& vec)
|
|||
std::stringstream s;
|
||||
for (auto const& item : vec)
|
||||
{
|
||||
s << item << "\n";
|
||||
s << " " << item << "\n";
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
@ -47,34 +47,41 @@ std::string vector_to_string(std::vector<mapnik::attribute_descriptor> const& ve
|
|||
std::stringstream s;
|
||||
for (auto const& item : vec)
|
||||
{
|
||||
s << item.get_name() << "\n";
|
||||
s << " " << item.get_name() << "\n";
|
||||
}
|
||||
return s.str();
|
||||
}
|
||||
|
||||
#define REQUIRE_FIELD_NAMES(fields, names) \
|
||||
INFO("fields:\n" + vector_to_string(fields) + "names:\n" + vector_to_string(names)); \
|
||||
REQUIRE(fields.size() == names.size()); \
|
||||
auto itr_a = fields.begin(); \
|
||||
auto const end_a = fields.end(); \
|
||||
auto itr_b = names.begin(); \
|
||||
for (; itr_a != end_a; ++itr_a, ++itr_b) \
|
||||
{ \
|
||||
CHECK(itr_a->get_name() == *itr_b); \
|
||||
} \
|
||||
|
||||
inline void require_field_names(std::vector<mapnik::attribute_descriptor> const &fields,
|
||||
std::initializer_list<std::string> const &names)
|
||||
{
|
||||
INFO("fields: " + vector_to_string(fields) + " names: " + vector_to_string(names));
|
||||
REQUIRE(fields.size() == names.size());
|
||||
auto itr_a = fields.begin();
|
||||
auto const end_a = fields.end();
|
||||
auto itr_b = names.begin();
|
||||
for (; itr_a != end_a; ++itr_a, ++itr_b)
|
||||
{
|
||||
CHECK(itr_a->get_name() == *itr_b);
|
||||
}
|
||||
REQUIRE_FIELD_NAMES(fields,names);
|
||||
}
|
||||
|
||||
#define REQUIRE_FIELD_TYPES(fields, types) \
|
||||
REQUIRE(fields.size() == types.size()); \
|
||||
auto itr_a = fields.begin(); \
|
||||
auto const end_a = fields.end(); \
|
||||
auto itr_b = types.begin(); \
|
||||
for (; itr_a != end_a; ++itr_a, ++itr_b) { \
|
||||
CHECK(itr_a->get_type() == *itr_b); \
|
||||
} \
|
||||
|
||||
inline void require_field_types(std::vector<mapnik::attribute_descriptor> const &fields,
|
||||
std::initializer_list<mapnik::eAttributeType> const &types) {
|
||||
REQUIRE(fields.size() == types.size());
|
||||
auto itr_a = fields.begin();
|
||||
auto const end_a = fields.end();
|
||||
auto itr_b = types.begin();
|
||||
for (; itr_a != end_a; ++itr_a, ++itr_b) {
|
||||
CHECK(itr_a->get_type() == *itr_b);
|
||||
}
|
||||
std::initializer_list<mapnik::eAttributeType> const &types)
|
||||
{
|
||||
REQUIRE_FIELD_TYPES(fields, types);
|
||||
}
|
||||
|
||||
inline mapnik::featureset_ptr all_features(mapnik::datasource_ptr ds) {
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
#include "catch.hpp"
|
||||
#include "ds_test_util.hpp"
|
||||
|
||||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
|
@ -629,5 +630,60 @@ TEST_CASE("geojson") {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("GeoJSON descriptor returns all field names")
|
||||
{
|
||||
mapnik::parameters params;
|
||||
params["type"] = "geojson";
|
||||
|
||||
std::string filename("./test/data/json/featurecollection-multipleprops.geojson");
|
||||
params["file"] = filename;
|
||||
|
||||
// cleanup in the case of a failed previous run
|
||||
if (mapnik::util::exists(filename + ".index"))
|
||||
{
|
||||
mapnik::util::remove(filename + ".index");
|
||||
}
|
||||
|
||||
for (auto create_index : { true, false })
|
||||
{
|
||||
if (create_index)
|
||||
{
|
||||
CHECK(!mapnik::util::exists(filename + ".index"));
|
||||
int ret = create_disk_index(filename);
|
||||
int ret_posix = (ret >> 8) & 0x000000ff;
|
||||
INFO(ret);
|
||||
INFO(ret_posix);
|
||||
CHECK(mapnik::util::exists(filename + ".index"));
|
||||
}
|
||||
|
||||
for (auto cache_features : {true, false})
|
||||
{
|
||||
params["cache_features"] = cache_features;
|
||||
auto ds = mapnik::datasource_cache::instance().create(params);
|
||||
REQUIRE(bool(ds));
|
||||
auto fields = ds->get_descriptor().get_descriptors();
|
||||
// TODO: this combo (cache_features==false and create_index==false)
|
||||
// exposes the case where not all field names are reported, which should
|
||||
// ideally be fixed, but how?
|
||||
if (cache_features == false && create_index == false)
|
||||
{
|
||||
std::initializer_list<std::string> names = {"one"};
|
||||
REQUIRE_FIELD_NAMES(fields, names);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::initializer_list<std::string> names = {"one", "two"};
|
||||
REQUIRE_FIELD_NAMES(fields, names);
|
||||
}
|
||||
|
||||
}
|
||||
// cleanup
|
||||
if (create_index && mapnik::util::exists(filename + ".index"))
|
||||
{
|
||||
mapnik::util::remove(filename + ".index");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,7 +143,7 @@ TEST_CASE("SVG parser") {
|
|||
auto const& errors = p.error_messages();
|
||||
REQUIRE(errors.size() == 3);
|
||||
REQUIRE(errors[0] == "Failed to parse color: \"fail\"");
|
||||
REQUIRE(errors[1] == "Failed to parse double: \"fail\"");
|
||||
REQUIRE(errors[1] == "Failed to parse SVG value: \"fail\"");
|
||||
REQUIRE(errors[2] == "Failed to parse color: \"fail\"");
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ TEST_CASE("SVG parser") {
|
|||
auto const& errors = p.error_messages();
|
||||
REQUIRE(errors.size() == 13);
|
||||
REQUIRE(errors[0] == "parse_rect: Invalid width");
|
||||
REQUIRE(errors[1] == "Failed to parse double: \"FAIL\"");
|
||||
REQUIRE(errors[1] == "Failed to parse SVG value: \"FAIL\"");
|
||||
REQUIRE(errors[2] == "parse_rect: Invalid height");
|
||||
REQUIRE(errors[3] == "parse_rect: Invalid rx");
|
||||
REQUIRE(errors[4] == "parse_rect: Invalid ry");
|
||||
|
@ -200,7 +200,7 @@ TEST_CASE("SVG parser") {
|
|||
{
|
||||
auto const& errors = p.error_messages();
|
||||
REQUIRE(errors.size() == 1);
|
||||
REQUIRE(errors[0] == "Failed to parse double (optional %) from FAIL");
|
||||
REQUIRE(errors[0] == "Failed to parse SVG value: \"FAIL\"");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ CONFIG_MAPNIK_LIBNAME='%(mapnik_libname)s'
|
|||
CONFIG_MAPNIK_LIBPATH="%(mapnik_libpath)s"
|
||||
CONFIG_DEP_LIBS='%(dep_libs)s'
|
||||
CONFIG_MAPNIK_LDFLAGS="%(ldflags)s"
|
||||
CONFIG_MAPNIK_INCLUDE="${CONFIG_PREFIX}/include -I${CONFIG_PREFIX}/include/mapnik/agg"
|
||||
CONFIG_MAPNIK_INCLUDE="${CONFIG_PREFIX}/include -I${CONFIG_PREFIX}/include/mapnik/agg -I${CONFIG_PREFIX}/include/mapnik"
|
||||
CONFIG_DEP_INCLUDES="%(dep_includes)s"
|
||||
CONFIG_CXXFLAGS="%(cxxflags)s"
|
||||
CONFIG_CXX='%(cxx)s'
|
||||
|
|
Loading…
Reference in a new issue