diff --git a/test/visual/config.hpp b/test/visual/config.hpp index 974383fa0..366574c06 100644 --- a/test/visual/config.hpp +++ b/test/visual/config.hpp @@ -43,6 +43,36 @@ struct map_size map_size() { } std::size_t width = 0; std::size_t height = 0; + std::size_t margin_left = 0; + std::size_t margin_right = 0; + std::size_t margin_top = 0; + std::size_t margin_bottom = 0; + + bool has_margin() const + { + return 0 != (margin_left | margin_right | margin_top | margin_bottom); + } + + void inflate_by_margin(mapnik::box2d & box) const + { + std::size_t xm = margin_left + margin_right; + if (xm > 0 && xm < width) + { + double pixel_width = box.width() / (width - xm); + box.minx_ -= pixel_width * margin_left; + box.maxx_ += pixel_width * margin_right; + } + std::size_t ym = margin_top + margin_bottom; + if (ym > 0 && ym < height) + { + double pixel_height = box.height() / (height - ym); + // FIXME this will swap top/bottom margins + // if map coordinate system has `y` growing in + // the same direction as screen coordinates + box.maxy_ += pixel_height * margin_top; + box.miny_ -= pixel_height * margin_bottom; + } + } }; struct config diff --git a/test/visual/parse_map_sizes.cpp b/test/visual/parse_map_sizes.cpp index d0df2db9d..9229d5dc9 100644 --- a/test/visual/parse_map_sizes.cpp +++ b/test/visual/parse_map_sizes.cpp @@ -25,20 +25,44 @@ #pragma GCC diagnostic push #include #include -#include +#include +#include #pragma GCC diagnostic pop -BOOST_FUSION_ADAPT_STRUCT ( - visual_tests::map_size, - (std::size_t, width) - (std::size_t, height) - ) - namespace visual_tests { namespace x3 = boost::spirit::x3; +namespace fusion = boost::fusion; + +using x3::attr; using x3::ulong_; -auto const map_size_rule = x3::rule {} = ulong_ >> ',' >> ulong_; + +using map_dimspec = fusion::deque; + +auto const map_dimspec_rule = x3::rule{} + = ulong_ >> '+' >> ulong_ >> '+' >> ulong_ + | attr(0UL) >> ulong_ >> attr(0UL) + ; + +auto const map_size_rule = x3::rule {} + = map_dimspec_rule[( + [](auto & ctx) { + auto & v = _val(ctx); + auto a1 = fusion::at_c<1>(_attr(ctx)); + v.margin_left = fusion::at_c<0>(_attr(ctx)); + v.margin_right = fusion::at_c<2>(_attr(ctx)); + v.width = v.margin_left + a1 + v.margin_right; + })] + >> ',' + >> map_dimspec_rule[( + [](auto & ctx) { + auto & v = _val(ctx); + auto a1 = fusion::at_c<1>(_attr(ctx)); + v.margin_top = fusion::at_c<0>(_attr(ctx)); + v.margin_bottom = fusion::at_c<2>(_attr(ctx)); + v.height = v.margin_top + a1 + v.margin_bottom; + })] + ; auto const map_sizes_grammar = x3::rule > {} = map_size_rule % ';' ; diff --git a/test/visual/runner.cpp b/test/visual/runner.cpp index 98ac7961f..af0f24ec5 100644 --- a/test/visual/runner.cpp +++ b/test/visual/runner.cpp @@ -352,14 +352,19 @@ result_list runner::test_one(runner::path_type const& style_path, } map.resize(size.width, size.height); - if (cfg.bbox.valid()) - { - map.zoom_to_box(cfg.bbox); - } - else + + auto bbox = cfg.bbox; + if (!bbox.valid()) { map.zoom_all(); + bbox = map.get_current_extent(); } + if (size.has_margin()) + { + size.inflate_by_margin(bbox); + } + map.zoom_to_box(bbox); + mapnik::util::apply_visitor(renderer_visitor(name, map, tiles_count,