Merge pull request #3580 from mapnik/v3.0.x-cherry
Cherry pick stable commits from master into v3.0.x branch
This commit is contained in:
commit
47443526a0
21 changed files with 184 additions and 386 deletions
31
.travis.yml
31
.travis.yml
|
@ -25,19 +25,27 @@ matrix:
|
|||
- os: linux
|
||||
sudo: false
|
||||
compiler: ": clang"
|
||||
env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8" TRIGGER=true
|
||||
env: JOBS=4 CXX="ccache g++-6" CC="gcc-6"
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test']
|
||||
packages: [ 'libstdc++-5-dev', 'xutils-dev']
|
||||
packages: [ 'libstdc++-6-dev', 'g++-6', 'xutils-dev']
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: ": clang"
|
||||
env: JOBS=8 MASON_PUBLISH=true CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9" TRIGGER=true
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test']
|
||||
packages: [ 'libstdc++-4.9-dev', 'xutils-dev']
|
||||
- os: linux
|
||||
sudo: false
|
||||
compiler: ": clang-coverage"
|
||||
env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.8 -Qunused-arguments" CC="clang-3.8"
|
||||
env: JOBS=8 COVERAGE=true CXX="ccache clang++-3.9 -Qunused-arguments" CC="clang-3.9"
|
||||
addons:
|
||||
apt:
|
||||
sources: [ 'ubuntu-toolchain-r-test']
|
||||
packages: ['libstdc++-5-dev', 'xutils-dev' ]
|
||||
packages: ['libstdc++-4.9-dev', 'xutils-dev' ]
|
||||
- os: osx
|
||||
compiler: ": clang-osx"
|
||||
# https://docs.travis-ci.com/user/languages/objective-c/#Supported-OS-X-iOS-SDK-versions
|
||||
|
@ -78,10 +86,12 @@ before_script:
|
|||
- source bootstrap.sh
|
||||
- |
|
||||
if [[ $(uname -s) == 'Linux' ]]; then
|
||||
mason install clang 3.8.0
|
||||
export PATH=$(mason prefix clang 3.8.0)/bin:${PATH}
|
||||
which clang++
|
||||
export LLVM_COV="$(mason prefix clang 3.8.0)/bin/llvm-cov"
|
||||
mason install clang++ 3.9.0
|
||||
export PATH=$(mason prefix clang++ 3.9.0)/bin:${PATH}
|
||||
mason install llvm-cov 3.9.0
|
||||
export PATH=$(mason prefix llvm-cov 3.9.0)/bin:${PATH}
|
||||
which llvm-cov
|
||||
export LLVM_COV="$(mason prefix llvm-cov 3.9.0)/bin/llvm-cov"
|
||||
fi
|
||||
- ccache --version
|
||||
- ccache -p || true
|
||||
|
@ -98,7 +108,10 @@ script:
|
|||
# (and might work) for the next build
|
||||
- DURATION=2400
|
||||
- scripts/travis-command-wrapper.py -s "date" -i 120 --deadline=$(( $(date +%s) + ${DURATION} )) make
|
||||
- make test
|
||||
- RESULT=0
|
||||
- make test || RESULT=$?
|
||||
# we allow visual failures with g++ for now: https://github.com/mapnik/mapnik/issues/3567
|
||||
- if [[ ${RESULT} != 0 ]] && [[ ${CXX} =~ 'clang++' ]]; then false; fi;
|
||||
- enabled ${COVERAGE} coverage
|
||||
- enabled ${BENCH} make bench
|
||||
|
||||
|
|
|
@ -95,6 +95,7 @@ function make_config() {
|
|||
echo "
|
||||
CXX = '$CXX'
|
||||
CC = '$CC'
|
||||
CUSTOM_CXXFLAGS = '-D_GLIBCXX_USE_CXX11_ABI=0'
|
||||
RUNTIME_LINK = 'static'
|
||||
INPUT_PLUGINS = 'all'
|
||||
PATH = '${MASON_LINKED_REL}/bin'
|
||||
|
|
2
deps/mapbox/variant
vendored
2
deps/mapbox/variant
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 9a115c5eb3c09509c70a57b25b283b6e1cbba919
|
||||
Subproject commit 6317a0b7406395729139327a83a71cfa14513fac
|
43
include/mapnik/cxx11_support.hpp
Normal file
43
include/mapnik/cxx11_support.hpp
Normal file
|
@ -0,0 +1,43 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* 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_CXX11_SUPPORT_HPP
|
||||
#define MAPNIK_CXX11_SUPPORT_HPP
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace mapnik {
|
||||
namespace detail {
|
||||
|
||||
template <bool B, typename T, typename F>
|
||||
using conditional_t = typename std::conditional<B, T, F>::type;
|
||||
|
||||
template <typename T>
|
||||
using decay_t = typename std::decay<T>::type;
|
||||
|
||||
template <bool B, typename T = void>
|
||||
using enable_if_t = typename std::enable_if<B, T>::type;
|
||||
|
||||
} // namespace detail
|
||||
} // namespace mapnik
|
||||
|
||||
#endif // MAPNIK_CXX11_SUPPORT_HPP
|
|
@ -28,7 +28,6 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
|
||||
// stl
|
||||
#include <bitset>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
@ -190,6 +189,8 @@ public:
|
|||
for (unsigned i = 0; i < THE_MAX; ++i)
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
if (str_copy == our_strings_[i])
|
||||
#pragma GCC diagnostic pop
|
||||
|
@ -203,6 +204,8 @@ public:
|
|||
}
|
||||
}
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
throw illegal_enum_value(std::string("Illegal enumeration value '") +
|
||||
str + "' for enum " + our_name_);
|
||||
|
@ -213,6 +216,8 @@ public:
|
|||
std::string as_string() const
|
||||
{
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunknown-pragmas" // clang+gcc
|
||||
#pragma GCC diagnostic ignored "-Wpragmas" // gcc
|
||||
#pragma GCC diagnostic ignored "-Wundefined-var-template"
|
||||
return our_strings_[value_];
|
||||
#pragma GCC diagnostic pop
|
||||
|
|
|
@ -68,16 +68,6 @@ public:
|
|||
box_elements_.push_back(box_element(box, repeat_key));
|
||||
}
|
||||
|
||||
inline void clear_box_elements()
|
||||
{
|
||||
box_elements_.clear();
|
||||
}
|
||||
|
||||
inline text_symbolizer_properties const& get_properties() const
|
||||
{
|
||||
return info_ptr_->properties;
|
||||
}
|
||||
|
||||
pixel_position_list const& get();
|
||||
|
||||
// Iterate over the given path, placing line-following labels or point labels with respect to label_spacing.
|
||||
|
|
|
@ -77,18 +77,18 @@ struct offset_converter
|
|||
return threshold_;
|
||||
}
|
||||
|
||||
void set_offset(double value)
|
||||
void set_offset(double val)
|
||||
{
|
||||
if (offset_ != value)
|
||||
if (offset_ != val)
|
||||
{
|
||||
offset_ = value;
|
||||
offset_ = val;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
void set_threshold(double value)
|
||||
void set_threshold(double val)
|
||||
{
|
||||
threshold_ = value;
|
||||
threshold_ = val;
|
||||
// no need to reset(), since threshold doesn't affect
|
||||
// offset vertices' computation, it only controls how
|
||||
// far will we be looking for self-intersections
|
||||
|
|
|
@ -120,11 +120,11 @@ public:
|
|||
return algorithm_;
|
||||
}
|
||||
|
||||
void set_simplify_algorithm(simplify_algorithm_e value)
|
||||
void set_simplify_algorithm(simplify_algorithm_e val)
|
||||
{
|
||||
if (algorithm_ != value)
|
||||
if (algorithm_ != val)
|
||||
{
|
||||
algorithm_ = value;
|
||||
algorithm_ = val;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
@ -134,11 +134,11 @@ public:
|
|||
return tolerance_;
|
||||
}
|
||||
|
||||
void set_simplify_tolerance(double value)
|
||||
void set_simplify_tolerance(double val)
|
||||
{
|
||||
if (tolerance_ != value)
|
||||
if (tolerance_ != val)
|
||||
{
|
||||
tolerance_ = value;
|
||||
tolerance_ = val;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -100,18 +100,13 @@ struct strict_value : value_base_type
|
|||
{
|
||||
strict_value() = default;
|
||||
|
||||
strict_value(const char* val)
|
||||
strict_value(const char* val) noexcept(false)
|
||||
: value_base_type(std::string(val)) {}
|
||||
|
||||
template <typename T>
|
||||
strict_value(T const& obj)
|
||||
: value_base_type(typename detail::mapnik_value_type<T>::type(obj))
|
||||
{}
|
||||
|
||||
template <typename T>
|
||||
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||
strict_value(T && obj)
|
||||
noexcept(std::is_nothrow_constructible<value_base_type, T && >::value)
|
||||
: value_base_type(std::forward<T>(obj))
|
||||
noexcept(std::is_nothrow_constructible<value_base_type, U>::value)
|
||||
: value_base_type(U(std::forward<T>(obj)))
|
||||
{}
|
||||
};
|
||||
|
||||
|
|
|
@ -32,15 +32,7 @@ template <typename T>
|
|||
using recursive_wrapper = typename mapbox::util::recursive_wrapper<T>;
|
||||
|
||||
template<typename... Types>
|
||||
class variant : public mapbox::util::variant<Types...>
|
||||
{
|
||||
public:
|
||||
// tell spirit that this is an adapted variant
|
||||
struct adapted_variant_tag;
|
||||
using types = std::tuple<Types...>;
|
||||
// inherit ctor's
|
||||
using mapbox::util::variant<Types...>::variant;
|
||||
};
|
||||
using variant = typename mapbox::util::variant<Types...>;
|
||||
|
||||
// unary visitor interface
|
||||
// const
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_UTIL_VARIANT_IO_HPP
|
||||
|
||||
|
||||
namespace mapnik { namespace util {
|
||||
namespace mapbox { namespace util {
|
||||
|
||||
namespace detail {
|
||||
|
||||
|
|
|
@ -47,30 +47,20 @@ class MAPNIK_DECL value : public value_base
|
|||
public:
|
||||
value() = default;
|
||||
|
||||
// conversion from type T is done via a temporary of type U, which
|
||||
// is determined by mapnik_value_type;
|
||||
// enable_if< decay<T> != value > is necessary to avoid ill-formed
|
||||
// recursion in noexcept specifier; and it also prevents using this
|
||||
// constructor where implicitly-declared copy/move should be used
|
||||
// (e.g. value(value&))
|
||||
template <typename T,
|
||||
typename U = typename std::enable_if<
|
||||
!detail::is_same_decay<T, value>::value,
|
||||
detail::mapnik_value_type_decay<T>
|
||||
>::type::type>
|
||||
// Conversion from type T is done via a temporary value or reference
|
||||
// of type U, which is determined by mapnik_value_type_t.
|
||||
//
|
||||
// CAVEAT: We don't check `noexcept(conversion from T to U)`.
|
||||
// But since the type U is either value_bool, value_integer,
|
||||
// value_double or T &&, this conversion SHOULD NEVER throw.
|
||||
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||
value(T && val)
|
||||
noexcept(noexcept(U(std::forward<T>(val))) &&
|
||||
std::is_nothrow_constructible<value_base, U && >::value)
|
||||
noexcept(std::is_nothrow_constructible<value_base, U>::value)
|
||||
: value_base(U(std::forward<T>(val))) {}
|
||||
|
||||
template <typename T,
|
||||
typename U = typename std::enable_if<
|
||||
!detail::is_same_decay<T, value>::value,
|
||||
detail::mapnik_value_type_decay<T>
|
||||
>::type::type>
|
||||
template <typename T, typename U = detail::mapnik_value_type_t<T>>
|
||||
value& operator=(T && val)
|
||||
noexcept(noexcept(U(std::forward<T>(val))) &&
|
||||
std::is_nothrow_assignable<value_base, U && >::value)
|
||||
noexcept(std::is_nothrow_assignable<value_base, U>::value)
|
||||
{
|
||||
value_base::operator=(U(std::forward<T>(val)));
|
||||
return *this;
|
||||
|
|
|
@ -37,11 +37,6 @@
|
|||
|
||||
namespace mapnik { namespace detail {
|
||||
|
||||
inline void hash_combine(std::size_t & seed, std::size_t val)
|
||||
{
|
||||
seed ^= val + 0x9e3779b9 + (seed << 6) + (seed >> 2);
|
||||
}
|
||||
|
||||
struct value_hasher
|
||||
{
|
||||
std::size_t operator() (value_null val) const
|
||||
|
@ -54,11 +49,6 @@ struct value_hasher
|
|||
return static_cast<std::size_t>(val.hashCode());
|
||||
}
|
||||
|
||||
std::size_t operator()(value_integer val) const
|
||||
{
|
||||
return static_cast<std::size_t>(val);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
std::size_t operator()(T const& val) const
|
||||
{
|
||||
|
@ -72,10 +62,7 @@ struct value_hasher
|
|||
template <typename T>
|
||||
std::size_t mapnik_hash_value(T const& val)
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
detail::hash_combine(seed, util::apply_visitor(detail::value_hasher(), val));
|
||||
detail::hash_combine(seed, val.which());
|
||||
return seed;
|
||||
return util::apply_visitor(detail::value_hasher(), val);
|
||||
}
|
||||
|
||||
} // namespace mapnik
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/cxx11_support.hpp>
|
||||
#include <mapnik/pixel_types.hpp>
|
||||
|
||||
|
||||
|
@ -34,7 +35,6 @@
|
|||
#pragma GCC diagnostic pop
|
||||
|
||||
// stl
|
||||
#include <type_traits>
|
||||
#include <iosfwd>
|
||||
#include <cstddef>
|
||||
|
||||
|
@ -152,90 +152,23 @@ inline std::istream& operator>> ( std::istream & s, value_null & )
|
|||
|
||||
|
||||
namespace detail {
|
||||
// to mapnik::value_type conversions traits
|
||||
template <typename T>
|
||||
struct is_value_bool
|
||||
{
|
||||
constexpr static bool value = std::is_same<T, bool>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_value_integer
|
||||
{
|
||||
constexpr static bool value = std::is_integral<T>::value && !std::is_same<T, bool>::value;
|
||||
};
|
||||
// Helper metafunction for mapnik::value construction and assignment.
|
||||
// Returns:
|
||||
// value_bool if T is bool
|
||||
// value_integer if T is an integral type (except bool)
|
||||
// value_double if T is a floating-point type
|
||||
// T && otherwise
|
||||
|
||||
template <typename T>
|
||||
struct is_value_double
|
||||
{
|
||||
constexpr static bool value = std::is_floating_point<T>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_value_unicode_string
|
||||
{
|
||||
constexpr static bool value = std::is_same<T, typename mapnik::value_unicode_string>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_value_string
|
||||
{
|
||||
constexpr static bool value = std::is_same<T, typename std::string>::value;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct is_value_null
|
||||
{
|
||||
constexpr static bool value = std::is_same<T, typename mapnik::value_null>::value;
|
||||
};
|
||||
|
||||
template <typename T, class Enable = void>
|
||||
struct mapnik_value_type
|
||||
{
|
||||
using type = T;
|
||||
};
|
||||
|
||||
// value_null
|
||||
template <typename T>
|
||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_null<T>::value>::type>
|
||||
{
|
||||
using type = mapnik::value_null;
|
||||
};
|
||||
|
||||
// value_bool
|
||||
template <typename T>
|
||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_bool<T>::value>::type>
|
||||
{
|
||||
using type = mapnik::value_bool;
|
||||
};
|
||||
|
||||
// value_integer
|
||||
template <typename T>
|
||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_integer<T>::value>::type>
|
||||
{
|
||||
using type = mapnik::value_integer;
|
||||
};
|
||||
|
||||
// value_double
|
||||
template <typename T>
|
||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_double<T>::value>::type>
|
||||
{
|
||||
using type = mapnik::value_double;
|
||||
};
|
||||
|
||||
// value_unicode_string
|
||||
template <typename T>
|
||||
struct mapnik_value_type<T, typename std::enable_if<detail::is_value_unicode_string<T>::value>::type>
|
||||
{
|
||||
using type = mapnik::value_unicode_string const&;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
using mapnik_value_type_decay = mapnik_value_type<typename std::decay<T>::type>;
|
||||
|
||||
template <typename T, typename U>
|
||||
using is_same_decay = std::is_same<typename std::decay<T>::type,
|
||||
typename std::decay<U>::type>;
|
||||
template <typename T, typename dT = decay_t<T>>
|
||||
using mapnik_value_type_t =
|
||||
conditional_t<
|
||||
std::is_same<dT, bool>::value, value_bool,
|
||||
conditional_t<
|
||||
std::is_integral<dT>::value, value_integer,
|
||||
conditional_t<
|
||||
std::is_floating_point<dT>::value, value_double,
|
||||
T && >>>;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
|
|
|
@ -83,9 +83,9 @@ config_override () {
|
|||
configure () {
|
||||
if enabled ${COVERAGE}; then
|
||||
./configure "$@" PREFIX=${PREFIX} PGSQL2SQLITE=False SVG2PNG=False SVG_RENDERER=False \
|
||||
COVERAGE=True DEBUG=True WARNING_CXXFLAGS="-Wno-unknown-warning-option"
|
||||
COVERAGE=True DEBUG=True
|
||||
else
|
||||
./configure "$@" PREFIX=${PREFIX} WARNING_CXXFLAGS="-Wno-unknown-warning-option"
|
||||
./configure "$@" PREFIX=${PREFIX}
|
||||
fi
|
||||
# print final config values, sorted and indented
|
||||
sort -sk1,1 ./config.py | sed -e 's/^/ /'
|
||||
|
|
|
@ -79,79 +79,22 @@ struct agg_renderer_process_visitor_l
|
|||
|
||||
void operator() (marker_svg const& marker) const
|
||||
{
|
||||
using color = agg::rgba8;
|
||||
using order = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
||||
using pattern_filter_type = agg::pattern_filter_bilinear_rgba8;
|
||||
using pattern_type = agg::line_image_pattern<pattern_filter_type>;
|
||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_type>;
|
||||
using renderer_type = agg::renderer_outline_image<renderer_base, pattern_type>;
|
||||
using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
|
||||
|
||||
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform, common_.scale_factor_);
|
||||
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
||||
image_rgba8 image(bbox_image.width(), bbox_image.height());
|
||||
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
||||
|
||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||
value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||
value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->bytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->row_size());
|
||||
pixfmt_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
||||
renderer_base ren_base(pixf);
|
||||
agg::pattern_filter_bilinear_rgba8 filter;
|
||||
|
||||
pattern_source source(image, opacity);
|
||||
pattern_type pattern (filter,source);
|
||||
renderer_type ren(ren_base, pattern);
|
||||
double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
|
||||
int rast_clip_padding = static_cast<int>(std::round(half_stroke));
|
||||
ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
|
||||
rasterizer_type ras(ren);
|
||||
|
||||
agg::trans_affine tr;
|
||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
||||
if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
||||
|
||||
box2d<double> clip_box = clipping_extent(common_);
|
||||
if (clip)
|
||||
{
|
||||
double padding = (double)(common_.query_extent_.width()/pixmap_.width());
|
||||
if (half_stroke > 1)
|
||||
padding *= half_stroke;
|
||||
if (std::fabs(offset) > 0)
|
||||
padding *= std::fabs(offset) * 1.2;
|
||||
padding *= common_.scale_factor_;
|
||||
clip_box.pad(padding);
|
||||
}
|
||||
using vertex_converter_type = vertex_converter<clip_line_tag, transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag,smooth_tag,
|
||||
offset_transform_tag>;
|
||||
|
||||
vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (clip) converter.set<clip_line_tag>();
|
||||
converter.set<transform_tag>(); //always transform
|
||||
if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
|
||||
if (std::fabs(offset) > 0.0) converter.set<offset_transform_tag>(); // parallel offset
|
||||
converter.set<affine_transform_tag>(); // optional affine transform
|
||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
|
||||
using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer_type>;
|
||||
using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
|
||||
apply_vertex_converter_type apply(converter, ras);
|
||||
mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry());
|
||||
render(image, marker.width(), marker.height());
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker) const
|
||||
{
|
||||
render(marker.get_data(), marker.width(), marker.height());
|
||||
}
|
||||
|
||||
private:
|
||||
void render(mapnik::image_rgba8 const& marker, double width, double height) const
|
||||
{
|
||||
using color = agg::rgba8;
|
||||
using order = agg::order_rgba;
|
||||
|
@ -164,8 +107,6 @@ struct agg_renderer_process_visitor_l
|
|||
using rasterizer_type = agg::rasterizer_outline_aa<renderer_type>;
|
||||
|
||||
value_double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||
mapnik::image_rgba8 const& image = marker.get_data();
|
||||
|
||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||
value_double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||
|
@ -178,10 +119,10 @@ struct agg_renderer_process_visitor_l
|
|||
renderer_base ren_base(pixf);
|
||||
agg::pattern_filter_bilinear_rgba8 filter;
|
||||
|
||||
pattern_source source(image, opacity);
|
||||
pattern_source source(marker, opacity);
|
||||
pattern_type pattern (filter,source);
|
||||
renderer_type ren(ren_base, pattern);
|
||||
double half_stroke = std::max(marker.width()/2.0,marker.height()/2.0);
|
||||
double half_stroke = std::max(width / 2.0, height / 2.0);
|
||||
int rast_clip_padding = static_cast<int>(std::round(half_stroke));
|
||||
ren.clip_box(-rast_clip_padding,-rast_clip_padding,common_.width_+rast_clip_padding,common_.height_+rast_clip_padding);
|
||||
rasterizer_type ras(ren);
|
||||
|
@ -221,7 +162,6 @@ struct agg_renderer_process_visitor_l
|
|||
mapnik::util::apply_visitor(vertex_processor_type(apply), feature_.get_geometry());
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common & common_;
|
||||
buffer_type & pixmap_;
|
||||
buffer_type * current_buffer_;
|
||||
|
|
|
@ -88,123 +88,17 @@ struct agg_renderer_process_visitor_p
|
|||
mapnik::box2d<double> const& bbox_image = marker.get_data()->bounding_box() * image_tr;
|
||||
mapnik::image_rgba8 image(bbox_image.width(), bbox_image.height());
|
||||
render_pattern<buffer_type>(*ras_ptr_, marker, image_tr, 1.0, image);
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->row_size());
|
||||
ras_ptr_->reset();
|
||||
value_double gamma = get<value_double, keys::gamma>(sym_, feature_, common_.vars_);
|
||||
gamma_method_enum gamma_method = get<gamma_method_enum, keys::gamma_method>(sym_, feature_, common_.vars_);
|
||||
if (gamma != gamma_ || gamma_method != gamma_method_)
|
||||
{
|
||||
set_gamma_method(ras_ptr_, gamma, gamma_method);
|
||||
gamma_method_ = gamma_method;
|
||||
gamma_ = gamma;
|
||||
}
|
||||
|
||||
value_bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||
value_double opacity = get<double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||
value_double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||
value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
||||
|
||||
box2d<double> clip_box = clipping_extent(common_);
|
||||
|
||||
using color = agg::rgba8;
|
||||
using order = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
|
||||
using wrap_x_type = agg::wrap_mode_repeat;
|
||||
using wrap_y_type = agg::wrap_mode_repeat;
|
||||
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
||||
wrap_x_type,
|
||||
wrap_y_type>;
|
||||
|
||||
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
||||
using ren_base = agg::renderer_base<pixfmt_type>;
|
||||
|
||||
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
||||
agg::span_allocator<agg::rgba8>,
|
||||
span_gen_type>;
|
||||
|
||||
pixfmt_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
||||
ren_base renb(pixf);
|
||||
|
||||
unsigned w = image.width();
|
||||
unsigned h = image.height();
|
||||
agg::rendering_buffer pattern_rbuf((agg::int8u*)image.bytes(),w,h,w*4);
|
||||
agg::pixfmt_rgba32_pre pixf_pattern(pattern_rbuf);
|
||||
img_source_type img_src(pixf_pattern);
|
||||
|
||||
pattern_alignment_enum alignment = get<pattern_alignment_enum, keys::alignment>(sym_, feature_, common_.vars_);
|
||||
unsigned offset_x=0;
|
||||
unsigned offset_y=0;
|
||||
|
||||
if (alignment == LOCAL_ALIGNMENT)
|
||||
{
|
||||
double x0 = 0;
|
||||
double y0 = 0;
|
||||
using apply_local_alignment = detail::apply_local_alignment;
|
||||
apply_local_alignment apply(common_.t_,prj_trans_, clip_box, x0, y0);
|
||||
util::apply_visitor(geometry::vertex_processor<apply_local_alignment>(apply), feature_.get_geometry());
|
||||
offset_x = unsigned(current_buffer_->width() - x0);
|
||||
offset_y = unsigned(current_buffer_->height() - y0);
|
||||
}
|
||||
|
||||
span_gen_type sg(img_src, offset_x, offset_y);
|
||||
|
||||
agg::span_allocator<agg::rgba8> sa;
|
||||
renderer_type rp(renb,sa, sg, unsigned(opacity * 255));
|
||||
|
||||
agg::trans_affine tr;
|
||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
||||
if (transform) evaluate_transform(tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
||||
using vertex_converter_type = vertex_converter<clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag,
|
||||
smooth_tag>;
|
||||
|
||||
vertex_converter_type converter(clip_box,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
|
||||
if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>();
|
||||
converter.set<transform_tag>(); //always transform
|
||||
converter.set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.set<smooth_tag>(); // optional smooth converter
|
||||
|
||||
using apply_vertex_converter_type = detail::apply_vertex_converter<vertex_converter_type, rasterizer>;
|
||||
using vertex_processor_type = geometry::vertex_processor<apply_vertex_converter_type>;
|
||||
apply_vertex_converter_type apply(converter, *ras_ptr_);
|
||||
mapnik::util::apply_visitor(vertex_processor_type(apply),feature_.get_geometry());
|
||||
agg::scanline_u8 sl;
|
||||
ras_ptr_->filling_rule(agg::fill_even_odd);
|
||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||
render(image);
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker) const
|
||||
{
|
||||
using color = agg::rgba8;
|
||||
using order = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
|
||||
using wrap_x_type = agg::wrap_mode_repeat;
|
||||
using wrap_y_type = agg::wrap_mode_repeat;
|
||||
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
||||
wrap_x_type,
|
||||
wrap_y_type>;
|
||||
|
||||
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
||||
using ren_base = agg::renderer_base<pixfmt_type>;
|
||||
|
||||
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
||||
agg::span_allocator<agg::rgba8>,
|
||||
span_gen_type>;
|
||||
mapnik::image_rgba8 const& image = marker.get_data();
|
||||
|
||||
render(marker.get_data());
|
||||
}
|
||||
|
||||
private:
|
||||
void render(mapnik::image_rgba8 const& image) const
|
||||
{
|
||||
agg::rendering_buffer buf(current_buffer_->bytes(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->row_size());
|
||||
ras_ptr_->reset();
|
||||
|
@ -224,6 +118,23 @@ struct agg_renderer_process_visitor_p
|
|||
|
||||
box2d<double> clip_box = clipping_extent(common_);
|
||||
|
||||
using color = agg::rgba8;
|
||||
using order = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color, order>;
|
||||
using pixfmt_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
|
||||
using wrap_x_type = agg::wrap_mode_repeat;
|
||||
using wrap_y_type = agg::wrap_mode_repeat;
|
||||
using img_source_type = agg::image_accessor_wrap<agg::pixfmt_rgba32_pre,
|
||||
wrap_x_type,
|
||||
wrap_y_type>;
|
||||
|
||||
using span_gen_type = agg::span_pattern_rgba<img_source_type>;
|
||||
using ren_base = agg::renderer_base<pixfmt_type>;
|
||||
|
||||
using renderer_type = agg::renderer_scanline_aa_alpha<ren_base,
|
||||
agg::span_allocator<agg::rgba8>,
|
||||
span_gen_type>;
|
||||
|
||||
pixfmt_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(get<composite_mode_e, keys::comp_op>(sym_, feature_, common_.vars_)));
|
||||
|
@ -282,7 +193,6 @@ struct agg_renderer_process_visitor_p
|
|||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common & common_;
|
||||
buffer_type * current_buffer_;
|
||||
std::unique_ptr<rasterizer> const& ras_ptr_;
|
||||
|
|
|
@ -90,30 +90,26 @@ struct process_layout
|
|||
return;
|
||||
}
|
||||
|
||||
bound_box layout_box;
|
||||
int middle_ifirst = safe_cast<int>((member_boxes_.size() - 1) >> 1);
|
||||
int top_i = 0;
|
||||
int bottom_i = 0;
|
||||
if (middle_ifirst % 2 == 0)
|
||||
auto max_diff = layout.get_max_difference();
|
||||
auto layout_box = make_horiz_pair(0, 0.0, 0, x_margin, max_diff);
|
||||
auto y_shift = 0.5 * layout_box.height();
|
||||
|
||||
for (size_t i = 2; i < member_boxes_.size(); i += 2)
|
||||
{
|
||||
layout_box = make_horiz_pair(0, 0.0, 0, x_margin, layout.get_max_difference());
|
||||
top_i = middle_ifirst - 2;
|
||||
bottom_i = middle_ifirst + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
top_i = middle_ifirst - 1;
|
||||
bottom_i = middle_ifirst + 1;
|
||||
auto y = layout_box.maxy() + y_margin;
|
||||
auto pair_box = make_horiz_pair(i, y, 1, x_margin, max_diff);
|
||||
layout_box.expand_to_include(pair_box);
|
||||
}
|
||||
|
||||
while (bottom_i >= 0 && top_i >= 0 && top_i < static_cast<int>(member_offsets_.size()))
|
||||
{
|
||||
layout_box.expand_to_include(make_horiz_pair(static_cast<std::size_t>(top_i), layout_box.miny() - y_margin, -1, x_margin, layout.get_max_difference()));
|
||||
layout_box.expand_to_include(make_horiz_pair(static_cast<std::size_t>(bottom_i), layout_box.maxy() + y_margin, 1, x_margin, layout.get_max_difference()));
|
||||
top_i -= 2;
|
||||
bottom_i += 2;
|
||||
}
|
||||
// layout_box.center corresponds to the center of the first row;
|
||||
// shift offsets so that the whole group is centered vertically
|
||||
|
||||
y_shift -= 0.5 * layout_box.height();
|
||||
|
||||
for (auto & offset : member_offsets_)
|
||||
{
|
||||
offset.y += y_shift;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -146,12 +142,12 @@ private:
|
|||
// stores corresponding offset, and returns modified bounding box
|
||||
bound_box box_offset_align(size_t i, double x, double y, int x_dir, int y_dir) const
|
||||
{
|
||||
bound_box const& box = member_boxes_[i];
|
||||
pixel_position offset((x_dir == 0 ? x - input_origin_.x : x - (x_dir < 0 ? box.maxx() : box.minx())),
|
||||
(y_dir == 0 ? y - input_origin_.y : y - (y_dir < 0 ? box.maxy() : box.miny())));
|
||||
|
||||
member_offsets_[i] = offset;
|
||||
return bound_box(box.minx() + offset.x, box.miny() + offset.y, box.maxx() + offset.x, box.maxy() + offset.y);
|
||||
auto box = member_boxes_[i];
|
||||
auto & offset = member_offsets_[i];
|
||||
offset.x = x - (x_dir == 0 ? input_origin_.x : (x_dir < 0 ? box.maxx() : box.minx()));
|
||||
offset.y = y - (y_dir == 0 ? input_origin_.y : (y_dir < 0 ? box.maxy() : box.miny()));
|
||||
box.move(offset.x, offset.y);
|
||||
return box;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
#include <mapnik/group/group_layout.hpp>
|
||||
#include <mapnik/group/group_symbolizer_properties.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/util/variant_io.hpp>
|
||||
#include <mapbox/variant_io.hpp>
|
||||
#pragma GCC diagnostic push
|
||||
#include <mapnik/warning_ignore.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 941db3d00920dc7aceaa6797096a7228bc7bac14
|
||||
Subproject commit f9a3c203b3657dd1748d788304f83a26efb6439f
|
|
@ -284,16 +284,19 @@ SECTION("to string") {
|
|||
REQUIRE( string2bool("true",val) );
|
||||
REQUIRE( val == true );
|
||||
|
||||
// mapnik::value hashability
|
||||
using values_container = std::unordered_map<mapnik::value, unsigned>;
|
||||
// mapnik::value hash() and operator== works for all T in value<Types...>
|
||||
mapnik::transcoder tr("utf8");
|
||||
using values_container = std::unordered_map<mapnik::value, mapnik::value>;
|
||||
values_container vc;
|
||||
mapnik::value val2(1);
|
||||
vc[val2] = 1;
|
||||
REQUIRE( vc[1] == static_cast<int>(1) );
|
||||
mapnik::value keys[5] = {true, 123456789, 3.14159f, tr.transcode("Мапник"), mapnik::value_null()} ;
|
||||
for (auto const& k : keys)
|
||||
{
|
||||
vc.insert({k, k});
|
||||
REQUIRE( vc[k] == k );
|
||||
}
|
||||
|
||||
// mapnik::value << to ostream
|
||||
std::stringstream s;
|
||||
mapnik::transcoder tr("utf-8");
|
||||
mapnik::value_unicode_string ustr = tr.transcode("hello world!");
|
||||
mapnik::value streamable(ustr);
|
||||
s << streamable;
|
||||
|
|
Loading…
Reference in a new issue