visual tests: support for Cairo PS, PDF and SVG renderers
This commit is contained in:
parent
52df451ee3
commit
464e508dc5
2 changed files with 137 additions and 35 deletions
|
@ -38,10 +38,21 @@
|
||||||
#if defined(GRID_RENDERER)
|
#if defined(GRID_RENDERER)
|
||||||
#include <mapnik/grid/grid_renderer.hpp>
|
#include <mapnik/grid/grid_renderer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_CAIRO)
|
#if defined(HAVE_CAIRO)
|
||||||
#include <mapnik/cairo/cairo_renderer.hpp>
|
#include <mapnik/cairo/cairo_renderer.hpp>
|
||||||
#include <mapnik/cairo/cairo_image_util.hpp>
|
#include <mapnik/cairo/cairo_image_util.hpp>
|
||||||
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
|
#include <cairo-svg.h>
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
|
#include <cairo-ps.h>
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
|
#include <cairo-pdf.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
#include <mapnik/svg/output/svg_renderer.hpp>
|
#include <mapnik/svg/output/svg_renderer.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
@ -53,7 +64,7 @@ namespace visual_tests
|
||||||
{
|
{
|
||||||
|
|
||||||
template <typename ImageType>
|
template <typename ImageType>
|
||||||
struct renderer_base
|
struct raster_renderer_base
|
||||||
{
|
{
|
||||||
using image_type = ImageType;
|
using image_type = ImageType;
|
||||||
|
|
||||||
|
@ -80,7 +91,35 @@ struct renderer_base
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct agg_renderer : renderer_base<mapnik::image_rgba8>
|
struct vector_renderer_base
|
||||||
|
{
|
||||||
|
using image_type = std::string;
|
||||||
|
|
||||||
|
static constexpr const bool support_tiles = false;
|
||||||
|
|
||||||
|
unsigned compare(image_type const & actual, boost::filesystem::path const& reference) const
|
||||||
|
{
|
||||||
|
std::ifstream stream(reference.string().c_str(), std::ios_base::in | std::ios_base::binary);
|
||||||
|
if (!stream)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not open: " + reference.string());
|
||||||
|
}
|
||||||
|
std::string expected(std::istreambuf_iterator<char>(stream.rdbuf()), std::istreambuf_iterator<char>());
|
||||||
|
return std::max(actual.size(), expected.size()) - std::min(actual.size(), expected.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
void save(image_type const & image, boost::filesystem::path const& path) const
|
||||||
|
{
|
||||||
|
std::ofstream file(path.string().c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
|
||||||
|
if (!file)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Cannot open file for writing: " + path.string());
|
||||||
|
}
|
||||||
|
file << image;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct agg_renderer : raster_renderer_base<mapnik::image_rgba8>
|
||||||
{
|
{
|
||||||
static constexpr const char * name = "agg";
|
static constexpr const char * name = "agg";
|
||||||
|
|
||||||
|
@ -94,7 +133,7 @@ struct agg_renderer : renderer_base<mapnik::image_rgba8>
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(HAVE_CAIRO)
|
#if defined(HAVE_CAIRO)
|
||||||
struct cairo_renderer : renderer_base<mapnik::image_rgba8>
|
struct cairo_renderer : raster_renderer_base<mapnik::image_rgba8>
|
||||||
{
|
{
|
||||||
static constexpr const char * name = "cairo";
|
static constexpr const char * name = "cairo";
|
||||||
|
|
||||||
|
@ -111,14 +150,65 @@ struct cairo_renderer : renderer_base<mapnik::image_rgba8>
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
using surface_create_type = cairo_surface_t *(&)(cairo_write_func_t, void *, double, double);
|
||||||
|
|
||||||
|
template <surface_create_type SurfaceCreateFunction>
|
||||||
|
struct cairo_vector_renderer : vector_renderer_base
|
||||||
|
{
|
||||||
|
static cairo_status_t write(void *closure,
|
||||||
|
const unsigned char *data,
|
||||||
|
unsigned int length)
|
||||||
|
{
|
||||||
|
std::ostringstream & ss = *reinterpret_cast<std::ostringstream*>(closure);
|
||||||
|
ss.write(reinterpret_cast<char const *>(data), length);
|
||||||
|
return ss ? CAIRO_STATUS_SUCCESS : CAIRO_STATUS_WRITE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
image_type render(mapnik::Map const & map, double scale_factor) const
|
||||||
|
{
|
||||||
|
std::ostringstream ss(std::stringstream::binary);
|
||||||
|
mapnik::cairo_surface_ptr image_surface(
|
||||||
|
SurfaceCreateFunction(write, &ss, map.width(), map.height()),
|
||||||
|
mapnik::cairo_surface_closer());
|
||||||
|
mapnik::cairo_ptr image_context(mapnik::create_context(image_surface));
|
||||||
|
mapnik::cairo_renderer<mapnik::cairo_ptr> ren(map, image_context, scale_factor);
|
||||||
|
ren.apply();
|
||||||
|
cairo_surface_finish(&*image_surface);
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
|
struct cairo_svg_renderer : cairo_vector_renderer<cairo_svg_surface_create_for_stream>
|
||||||
|
{
|
||||||
|
static constexpr const char * name = "cairo-svg";
|
||||||
|
static constexpr const char * ext = ".svg";
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
|
struct cairo_ps_renderer : cairo_vector_renderer<cairo_ps_surface_create_for_stream>
|
||||||
|
{
|
||||||
|
static constexpr const char * name = "cairo-ps";
|
||||||
|
static constexpr const char * ext = ".ps";
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
|
struct cairo_pdf_renderer : cairo_vector_renderer<cairo_pdf_surface_create_for_stream>
|
||||||
|
{
|
||||||
|
static constexpr const char * name = "cairo-pdf";
|
||||||
|
static constexpr const char * ext = ".pdf";
|
||||||
|
};
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
struct svg_renderer : renderer_base<std::string>
|
struct svg_renderer : vector_renderer_base
|
||||||
{
|
{
|
||||||
static constexpr const char * name = "svg";
|
static constexpr const char * name = "svg";
|
||||||
static constexpr const char * ext = ".svg";
|
static constexpr const char * ext = ".svg";
|
||||||
static constexpr const bool support_tiles = false;
|
|
||||||
|
|
||||||
image_type render(mapnik::Map const & map, double scale_factor) const
|
image_type render(mapnik::Map const & map, double scale_factor) const
|
||||||
{
|
{
|
||||||
|
@ -128,35 +218,11 @@ struct svg_renderer : renderer_base<std::string>
|
||||||
ren.apply();
|
ren.apply();
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned compare(image_type const & actual, boost::filesystem::path const& reference) const
|
|
||||||
{
|
|
||||||
std::ifstream stream(reference.string().c_str(),std::ios_base::in|std::ios_base::binary);
|
|
||||||
if (!stream.is_open())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("could not open: '" + reference.string() + "'");
|
|
||||||
}
|
|
||||||
std::string expected(std::istreambuf_iterator<char>(stream.rdbuf()),(std::istreambuf_iterator<char>()));
|
|
||||||
stream.close();
|
|
||||||
return std::max(actual.size(), expected.size()) - std::min(actual.size(), expected.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
void save(image_type const & image, boost::filesystem::path const& path) const
|
|
||||||
{
|
|
||||||
std::ofstream file(path.string().c_str(), std::ios::out | std::ios::trunc | std::ios::binary);
|
|
||||||
if (!file) {
|
|
||||||
throw std::runtime_error((std::string("cannot open file for writing file ") + path.string()).c_str());
|
|
||||||
} else {
|
|
||||||
file << image;
|
|
||||||
file.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(GRID_RENDERER)
|
#if defined(GRID_RENDERER)
|
||||||
struct grid_renderer : renderer_base<mapnik::image_rgba8>
|
struct grid_renderer : raster_renderer_base<mapnik::image_rgba8>
|
||||||
{
|
{
|
||||||
static constexpr const char * name = "grid";
|
static constexpr const char * name = "grid";
|
||||||
|
|
||||||
|
@ -335,6 +401,15 @@ private:
|
||||||
using renderer_type = mapnik::util::variant<renderer<agg_renderer>
|
using renderer_type = mapnik::util::variant<renderer<agg_renderer>
|
||||||
#if defined(HAVE_CAIRO)
|
#if defined(HAVE_CAIRO)
|
||||||
,renderer<cairo_renderer>
|
,renderer<cairo_renderer>
|
||||||
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
|
,renderer<cairo_svg_renderer>
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
|
,renderer<cairo_ps_renderer>
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
|
,renderer<cairo_pdf_renderer>
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
,renderer<svg_renderer>
|
,renderer<svg_renderer>
|
||||||
|
|
|
@ -48,30 +48,48 @@ namespace po = boost::program_options;
|
||||||
|
|
||||||
runner::renderer_container create_renderers(po::variables_map const & args,
|
runner::renderer_container create_renderers(po::variables_map const & args,
|
||||||
boost::filesystem::path const & output_dir,
|
boost::filesystem::path const & output_dir,
|
||||||
bool append_all = false)
|
bool force_append = false)
|
||||||
{
|
{
|
||||||
boost::filesystem::path reference_dir(args["images-dir"].as<std::string>());
|
boost::filesystem::path reference_dir(args["images-dir"].as<std::string>());
|
||||||
bool overwrite = args.count("overwrite");
|
bool overwrite = args.count("overwrite");
|
||||||
runner::renderer_container renderers;
|
runner::renderer_container renderers;
|
||||||
|
|
||||||
if (append_all || args.count(agg_renderer::name))
|
if (force_append || args.count(agg_renderer::name))
|
||||||
{
|
{
|
||||||
renderers.emplace_back(renderer<agg_renderer>(output_dir, reference_dir, overwrite));
|
renderers.emplace_back(renderer<agg_renderer>(output_dir, reference_dir, overwrite));
|
||||||
}
|
}
|
||||||
#if defined(HAVE_CAIRO)
|
#if defined(HAVE_CAIRO)
|
||||||
if (append_all || args.count(cairo_renderer::name))
|
if (force_append || args.count(cairo_renderer::name))
|
||||||
{
|
{
|
||||||
renderers.emplace_back(renderer<cairo_renderer>(output_dir, reference_dir, overwrite));
|
renderers.emplace_back(renderer<cairo_renderer>(output_dir, reference_dir, overwrite));
|
||||||
}
|
}
|
||||||
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
|
if (args.count(cairo_svg_renderer::name))
|
||||||
|
{
|
||||||
|
renderers.emplace_back(renderer<cairo_svg_renderer>(output_dir, reference_dir, overwrite));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
|
if (args.count(cairo_ps_renderer::name))
|
||||||
|
{
|
||||||
|
renderers.emplace_back(renderer<cairo_ps_renderer>(output_dir, reference_dir, overwrite));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
|
if (args.count(cairo_pdf_renderer::name))
|
||||||
|
{
|
||||||
|
renderers.emplace_back(renderer<cairo_pdf_renderer>(output_dir, reference_dir, overwrite));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
if (append_all || args.count(svg_renderer::name))
|
if (force_append || args.count(svg_renderer::name))
|
||||||
{
|
{
|
||||||
renderers.emplace_back(renderer<svg_renderer>(output_dir, reference_dir, overwrite));
|
renderers.emplace_back(renderer<svg_renderer>(output_dir, reference_dir, overwrite));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(GRID_RENDERER)
|
#if defined(GRID_RENDERER)
|
||||||
if (append_all || args.count(grid_renderer::name))
|
if (force_append || args.count(grid_renderer::name))
|
||||||
{
|
{
|
||||||
renderers.emplace_back(renderer<grid_renderer>(output_dir, reference_dir, overwrite));
|
renderers.emplace_back(renderer<grid_renderer>(output_dir, reference_dir, overwrite));
|
||||||
}
|
}
|
||||||
|
@ -112,6 +130,15 @@ int main(int argc, char** argv)
|
||||||
(agg_renderer::name, "render with AGG renderer")
|
(agg_renderer::name, "render with AGG renderer")
|
||||||
#if defined(HAVE_CAIRO)
|
#if defined(HAVE_CAIRO)
|
||||||
(cairo_renderer::name, "render with Cairo renderer")
|
(cairo_renderer::name, "render with Cairo renderer")
|
||||||
|
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||||
|
(cairo_svg_renderer::name, "render with Cairo SVG renderer")
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PS_SURFACE
|
||||||
|
(cairo_ps_renderer::name, "render with Cairo PS renderer")
|
||||||
|
#endif
|
||||||
|
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||||
|
(cairo_pdf_renderer::name, "render with Cairo PDF renderer")
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if defined(SVG_RENDERER)
|
#if defined(SVG_RENDERER)
|
||||||
(svg_renderer::name, "render with SVG renderer")
|
(svg_renderer::name, "render with SVG renderer")
|
||||||
|
|
Loading…
Reference in a new issue