Merge pull request #2398 from mapnik/3x-msvs

Support for Windows 2013/2014 + C++11
This commit is contained in:
Dane Springmeyer 2014-09-04 16:43:12 -07:00
commit 41e07e3083
24 changed files with 102 additions and 88 deletions

View file

@ -25,7 +25,6 @@
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/config.hpp>
// stl
#include <cassert>
@ -35,7 +34,7 @@
namespace mapnik
{
template <typename T>
class MAPNIK_DECL ImageData
class ImageData
{
public:
using pixel_type = T;

View file

@ -205,7 +205,6 @@ public:
void reset_buffer_size();
~layer();
private:
friend void swap(layer & lhs, layer & rhs);
std::string name_;
std::string srs_;
double min_zoom_;

View file

@ -25,7 +25,8 @@
#include <memory>
#if __cplusplus <= 201103L
// http://stackoverflow.com/questions/14131454/visual-studio-2012-cplusplus-and-c-11
#if defined(_MSC_VER) && _MSC_VER < 1800 || !defined(_MSC_VER) && __cplusplus <= 201103L
namespace std {

View file

@ -100,6 +100,13 @@ boost::optional<mapnik::boolean_type> parameters::get(std::string const& key) co
template MAPNIK_DECL
boost::optional<mapnik::boolean_type> parameters::get(std::string const& key,
mapnik::boolean_type const& default_opt_value) const;
template MAPNIK_DECL
boost::optional<mapnik::value_null> parameters::get(std::string const& key) const;
template MAPNIK_DECL
boost::optional<mapnik::value_null> parameters::get(std::string const& key,
mapnik::value_null const& default_opt_value) const;
#endif
}

View file

@ -28,6 +28,7 @@
#include <mapnik/geometry.hpp>
#include <algorithm>
#include <deque>
namespace mapnik {

View file

@ -85,8 +85,6 @@ public:
syms_.reserve(size);
}
private:
friend void swap(rule & lhs, rule & rhs);
};
}

View file

@ -538,12 +538,6 @@ boost::optional<T> get_optional(symbolizer_base const& sym, keys key)
return boost::optional<T>();
}
template<typename Enum>
constexpr auto to_integral(Enum e) -> typename std::underlying_type<Enum>::type
{
return static_cast<typename std::underlying_type<Enum>::type>(e);
}
using property_meta_type = std::tuple<const char*, mapnik::symbolizer_base::value_type, std::function<std::string(enumeration_wrapper)>, property_types>;
MAPNIK_DECL property_meta_type const& get_meta(mapnik::keys key);
MAPNIK_DECL mapnik::keys get_key(std::string const& name);

View file

@ -29,15 +29,31 @@
#include <mapnik/text/face.hpp>
// stl
#include <list>
#include <type_traits>
// harfbuzz
#include <harfbuzz/hb.h>
#include <harfbuzz/hb-ft.h>
#include <harfbuzz/hb-icu.h>
namespace mapnik
{
static inline hb_script_t _icu_script_to_script(UScriptCode script)
{
if (script == USCRIPT_INVALID_CODE) return HB_SCRIPT_INVALID;
return hb_script_from_string(uscript_getShortName(script), -1);
}
static inline const uint16_t * uchar_to_utf16(const UChar* src)
{
static_assert(sizeof(UChar) == sizeof(uint16_t),"UChar is eq size to uint16_t");
#if defined(_MSC_VER)
return reinterpret_cast<const uint16_t *>(src);
#else
return src;
#endif
}
struct harfbuzz_shaper
{
static void shape_text(text_line & line,
@ -55,7 +71,6 @@ static void shape_text(text_line & line,
auto hb_buffer_deleter = [](hb_buffer_t * buffer) { hb_buffer_destroy(buffer);};
const std::unique_ptr<hb_buffer_t, decltype(hb_buffer_deleter)> buffer(hb_buffer_create(),hb_buffer_deleter);
hb_buffer_set_unicode_funcs(buffer.get(), hb_icu_get_unicode_funcs());
hb_buffer_pre_allocate(buffer.get(), length);
mapnik::value_unicode_string const& text = itemizer.text();
@ -70,9 +85,9 @@ static void shape_text(text_line & line,
{
++pos;
hb_buffer_clear_contents(buffer.get());
hb_buffer_add_utf16(buffer.get(), text.getBuffer(), text.length(), text_item.start, text_item.end - text_item.start);
hb_buffer_add_utf16(buffer.get(), uchar_to_utf16(text.getBuffer()), text.length(), text_item.start, text_item.end - text_item.start);
hb_buffer_set_direction(buffer.get(), (text_item.rtl == UBIDI_RTL)?HB_DIRECTION_RTL:HB_DIRECTION_LTR);
hb_buffer_set_script(buffer.get(), hb_icu_script_to_script(text_item.script));
hb_buffer_set_script(buffer.get(), _icu_script_to_script(text_item.script));
hb_font_t *font(hb_ft_font_create(face->get_face(), nullptr));
hb_shape(font, buffer.get(), nullptr, 0);
hb_font_destroy(font);

View file

@ -34,6 +34,7 @@
// stl
#include <tuple>
#include <cstring> // required for memcpy with linux/g++
#include <cstdint>
namespace mapnik
{

View file

@ -29,6 +29,9 @@
#include <mapnik/noncopyable.hpp>
// boost
#include <boost/optional.hpp>
// stl
#include <memory>
#include "dbfile.hpp"

View file

@ -46,7 +46,7 @@ namespace mapnik {
struct thunk_renderer : public util::static_visitor<>
{
using renderer_type = agg_renderer<image_32>;
using buffer_type = typename renderer_type::buffer_type;
using buffer_type = renderer_type::buffer_type;
using text_renderer_type = agg_text_renderer<buffer_type>;
thunk_renderer(renderer_type &ren,

View file

@ -61,21 +61,16 @@ feature_type_style::feature_type_style(feature_type_style const& rhs)
}
feature_type_style& feature_type_style::operator=(feature_type_style rhs)
{
swap(*this, rhs);
return *this;
}
void swap( feature_type_style & lhs, feature_type_style & rhs)
{
using std::swap;
std::swap(lhs.rules_, rhs.rules_);
std::swap(lhs.filter_mode_, rhs.filter_mode_);
std::swap(lhs.filters_, rhs.filters_);
std::swap(lhs.direct_filters_, rhs.direct_filters_);
std::swap(lhs.comp_op_, rhs.comp_op_);
std::swap(lhs.opacity_, rhs.opacity_);
std::swap(lhs.image_filters_inflate_, rhs.image_filters_inflate_);
std::swap(this->rules_, rhs.rules_);
std::swap(this->filter_mode_, rhs.filter_mode_);
std::swap(this->filters_, rhs.filters_);
std::swap(this->direct_filters_, rhs.direct_filters_);
std::swap(this->comp_op_, rhs.comp_op_);
std::swap(this->opacity_, rhs.opacity_);
std::swap(this->image_filters_inflate_, rhs.image_filters_inflate_);
return *this;
}
bool feature_type_style::operator==(feature_type_style const& rhs) const

View file

@ -31,7 +31,6 @@ namespace mapnik {
struct exp_impl
{
//using type = T;
static constexpr char const* name = "exp";
value_type operator() (value_type const& val) const
{
return std::exp(val.to_double());
@ -42,7 +41,6 @@ struct exp_impl
// sin
struct sin_impl
{
static constexpr char const* name = "sin";
value_type operator() (value_type const& val) const
{
return std::sin(val.to_double());
@ -52,7 +50,6 @@ struct sin_impl
// cos
struct cos_impl
{
static constexpr char const* name = "cos";
value_type operator() (value_type const& val) const
{
return std::cos(val.to_double());
@ -62,7 +59,6 @@ struct cos_impl
// tan
struct tan_impl
{
static constexpr char const* name = "tan";
value_type operator() (value_type const& val) const
{
return std::tan(val.to_double());
@ -72,7 +68,6 @@ struct tan_impl
// atan
struct atan_impl
{
static constexpr char const* name = "atan";
value_type operator()(value_type const& val) const
{
return std::atan(val.to_double());
@ -82,7 +77,6 @@ struct atan_impl
// abs
struct abs_impl
{
static constexpr char const* name = "abs";
value_type operator() (value_type const& val) const
{
return std::fabs(val.to_double());

View file

@ -73,27 +73,22 @@ layer::layer(layer && rhs)
maximum_extent_(std::move(rhs.maximum_extent_)) {}
layer& layer::operator=(layer rhs)
{
swap(*this, rhs);
return *this;
}
void swap(layer & lhs, layer & rhs)
{
using std::swap;
std::swap(lhs.name_,rhs.name_);
std::swap(lhs.srs_, rhs.srs_);
std::swap(lhs.min_zoom_, rhs.min_zoom_);
std::swap(lhs.max_zoom_,rhs.max_zoom_);
std::swap(lhs.active_, rhs.active_);
std::swap(lhs.queryable_, rhs.queryable_);
std::swap(lhs.clear_label_cache_, rhs.clear_label_cache_);
std::swap(lhs.cache_features_, rhs.cache_features_);
std::swap(lhs.group_by_, rhs.group_by_);
std::swap(lhs.styles_, rhs.styles_);
std::swap(lhs.ds_, rhs.ds_);
std::swap(lhs.buffer_size_, rhs.buffer_size_);
std::swap(lhs.maximum_extent_, rhs.maximum_extent_);
std::swap(this->name_,rhs.name_);
std::swap(this->srs_, rhs.srs_);
std::swap(this->min_zoom_, rhs.min_zoom_);
std::swap(this->max_zoom_,rhs.max_zoom_);
std::swap(this->active_, rhs.active_);
std::swap(this->queryable_, rhs.queryable_);
std::swap(this->clear_label_cache_, rhs.clear_label_cache_);
std::swap(this->cache_features_, rhs.cache_features_);
std::swap(this->group_by_, rhs.group_by_);
std::swap(this->styles_, rhs.styles_);
std::swap(this->ds_, rhs.ds_);
std::swap(this->buffer_size_, rhs.buffer_size_);
std::swap(this->maximum_extent_, rhs.maximum_extent_);
return *this;
}
bool layer::operator==(layer const& rhs) const

View file

@ -61,7 +61,14 @@ rule::rule(rule const& rhs)
rule& rule::operator=(rule rhs)
{
swap(*this, rhs);
using std::swap;
swap(this->name_, rhs.name_);
swap(this->min_scale_, rhs.min_scale_);
swap(this->max_scale_, rhs.max_scale_);
swap(this->syms_, rhs.syms_);
swap(this->filter_, rhs.filter_);
swap(this->else_filter_, rhs.else_filter_);
swap(this->also_filter_, rhs.also_filter_);
return *this;
}
@ -76,18 +83,6 @@ bool rule::operator==(rule const& rhs) const
(also_filter_ == rhs.also_filter_);
}
void swap(rule & lhs, rule & rhs)
{
using std::swap;
swap(lhs.name_, rhs.name_);
swap(lhs.min_scale_, rhs.min_scale_);
swap(lhs.max_scale_, rhs.max_scale_);
swap(lhs.syms_, rhs.syms_);
swap(lhs.filter_, rhs.filter_);
swap(lhs.else_filter_, rhs.else_filter_);
swap(lhs.also_filter_, rhs.also_filter_);
}
void rule::set_max_scale(double scale)
{
max_scale_=scale;

View file

@ -29,8 +29,10 @@
namespace mapnik {
static constexpr std::uint8_t const_max_key = static_cast<std::uint8_t>(keys::MAX_SYMBOLIZER_KEY);
// tuple -> name, default value, enumeration to string converter lambda, target property type
static const property_meta_type key_meta[to_integral(keys::MAX_SYMBOLIZER_KEY)] =
static const property_meta_type key_meta[const_max_key] =
{
property_meta_type{ "gamma", 1.0, nullptr, property_types::target_double},
property_meta_type{ "gamma-method", static_cast<value_integer>(GAMMA_POWER), nullptr, property_types::target_gamma_method},
@ -127,7 +129,7 @@ mapnik::keys get_key(std::string const& name)
{
std::string name_copy(name);
boost::algorithm::replace_all(name_copy,"_","-");
for (unsigned i=0; i< to_integral(keys::MAX_SYMBOLIZER_KEY) ; ++i)
for (unsigned i=0; i< const_max_key ; ++i)
{
property_meta_type const& item = key_meta[i];
if (name_copy == std::get<0>(item))
@ -139,4 +141,4 @@ mapnik::keys get_key(std::string const& name)
return static_cast<mapnik::keys>(0);
}
}
}

View file

@ -20,12 +20,10 @@
*
*****************************************************************************/
// mapnik
#include <mapnik/global.hpp>
#include <mapnik/text/vertex_cache.hpp>
#include <mapnik/offset_converter.hpp>
// boost
namespace mapnik
{

View file

@ -5,13 +5,13 @@
#include <vector>
#include <algorithm>
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER < 1900
#include <cstdio>
#endif
int main(int argc, char** argv)
{
#if defined(_MSC_VER)
#if defined(_MSC_VER) && _MSC_VER < 1900
unsigned int old = _set_output_format(_TWO_DIGIT_EXPONENT);
#endif
std::vector<std::string> args;

View file

@ -22,13 +22,12 @@ int main(int argc, char** argv)
try
{
mapnik::image_data_32 im(256,256);
unsigned char* bytes = im.getBytes();
mapnik::image_data_32 * im_ptr = new mapnik::image_data_32(256,256,(unsigned int *)bytes);
unsigned char* same_bytes = im_ptr->getBytes();
BOOST_TEST(bytes == same_bytes);
mapnik::image_data_32::pixel_type * data = im.getData();
mapnik::image_data_32 * im_ptr = new mapnik::image_data_32(im.width(),im.height(),data);
mapnik::image_data_32::pixel_type * same_data = im_ptr->getData();
BOOST_TEST(data == same_data);
delete im_ptr;
BOOST_TEST(bytes == same_bytes);
BOOST_TEST(data == same_data);
BOOST_TEST(set_working_dir(args));
#if defined(HAVE_JPEG)

View file

@ -403,6 +403,17 @@ if 'csv' in mapnik.DatasourceCache.plugin_names():
feat = fs.next()
eq_(feat['Name'],u"Winthrop, WA")
def test_creation_of_csv_from_in_memory_string_with_uft8(**kwargs):
csv_string = '''
wkt,Name
"POINT (120.15 48.47)","Québec"
''' # csv plugin will test lines <= 10 chars for being fully blank
ds = mapnik.Datasource(**{"type":"csv","inline":csv_string})
eq_(ds.describe()['geometry_type'],mapnik.DataGeometryType.Point)
fs = ds.featureset()
feat = fs.next()
eq_(feat['Name'],u"Québec")
def validate_geojson_datasource(ds):
eq_(len(ds.fields()),1)
eq_(ds.fields(),['type'])

View file

@ -10,21 +10,21 @@ import os, sys, glob, mapnik
def test_mapnik_config_no_args():
process = Popen('mapnik-config', shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
result = process.communicate()
eq_('Usage: mapnik-config ' in result[0],True)
eq_('Usage: mapnik-config' in result[0],True)
eq_(result[1],'')
eq_(process.returncode,1)
def test_mapnik_config_help():
process = Popen('mapnik-config --help', shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
result = process.communicate()
eq_('Usage: mapnik-config ' in result[0],True)
eq_('Usage: mapnik-config' in result[0],True)
eq_(result[1],'')
eq_(process.returncode,0)
def test_mapnik_config_help_short():
process = Popen('mapnik-config -h', shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
result = process.communicate()
eq_('Usage: mapnik-config ' in result[0],True)
eq_('Usage: mapnik-config' in result[0],True)
eq_(result[1],'')
eq_(process.returncode,0)

View file

@ -31,7 +31,10 @@ def call(cmd,silent=False):
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
if not stderr:
return stdin.strip()
elif not silent and 'error' in stderr.lower() or 'could not connect' in stderr.lower():
elif not silent and 'error' in stderr.lower() \
or 'could not connect' in stderr.lower() \
or 'bad connection' in stderr.lower() \
or 'not recognized as an internal' in stderr.lower():
raise RuntimeError(stderr.strip())
def psql_can_connect():

View file

@ -23,7 +23,10 @@ def call(cmd,silent=False):
stdin, stderr = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE).communicate()
if not stderr:
return stdin.strip()
elif not silent and 'error' in stderr.lower() or 'could not connect' in stderr.lower():
elif not silent and 'error' in stderr.lower() \
or 'could not connect' in stderr.lower() \
or 'bad connection' in stderr.lower() \
or 'not recognized as an internal' in stderr.lower():
raise RuntimeError(stderr.strip())
def psql_can_connect():

View file

@ -54,7 +54,8 @@ def compare_map(xml):
def test_compare_map():
good_maps = glob.glob("../data/good_maps/*.xml")
# remove one map that round trips CDATA differently, but this is okay
good_maps.remove('../data/good_maps/empty_parameter2.xml')
ignorable = os.path.join('..','data','good_maps','empty_parameter2.xml')
good_maps.remove(ignorable)
for m in good_maps:
compare_map(m)