Merge pull request #2712 from mapnik/release/image_data_any
Release/image data any
This commit is contained in:
commit
dc0cfef4bb
221 changed files with 8898 additions and 3168 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@
|
|||
*.os
|
||||
*.so
|
||||
*.a
|
||||
*.swp
|
||||
*.dylib
|
||||
plugins/input/*.input
|
||||
plugins/input/templates/*.input
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
#ifndef __MAPNIK_COMPARE_IMAGES_HPP__
|
||||
#define __MAPNIK_COMPARE_IMAGES_HPP__
|
||||
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
|
||||
|
@ -17,19 +16,15 @@ namespace benchmark {
|
|||
{
|
||||
throw mapnik::image_reader_exception("Failed to load: " + dest_fn);
|
||||
}
|
||||
std::shared_ptr<image_32> image_ptr1 = std::make_shared<image_32>(reader1->width(),reader1->height());
|
||||
reader1->read(0,0,image_ptr1->data());
|
||||
|
||||
std::unique_ptr<mapnik::image_reader> reader2(mapnik::get_image_reader(src_fn,"png"));
|
||||
if (!reader2.get())
|
||||
{
|
||||
throw mapnik::image_reader_exception("Failed to load: " + src_fn);
|
||||
}
|
||||
std::shared_ptr<image_32> image_ptr2 = std::make_shared<image_32>(reader2->width(),reader2->height());
|
||||
reader2->read(0,0,image_ptr2->data());
|
||||
|
||||
image_data_rgba8 const& dest = image_ptr1->data();
|
||||
image_data_rgba8 const& src = image_ptr2->data();
|
||||
image_rgba8 const& dest = util::get<image_rgba8>(reader1->read(0,0,reader1->width(), reader1->height()));
|
||||
image_rgba8 const& src = util::get<image_rgba8>(reader1->read(0,0,reader1->width(), reader1->height()));
|
||||
|
||||
unsigned int width = src.width();
|
||||
unsigned int height = src.height();
|
||||
|
|
|
@ -24,4 +24,4 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
BENCHMARK(test,"font registration")
|
||||
BENCHMARK(test,"font registration")
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
#include "bench_framework.hpp"
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
|
||||
class test : public benchmark::test_case
|
||||
{
|
||||
mapnik::image_data_rgba8 im_;
|
||||
mapnik::image_rgba8 im_;
|
||||
public:
|
||||
test(mapnik::parameters const& params)
|
||||
: test_case(params),
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
class test : public benchmark::test_case
|
||||
{
|
||||
std::shared_ptr<image_32> im_;
|
||||
std::shared_ptr<image_rgba8> im_;
|
||||
public:
|
||||
test(mapnik::parameters const& params)
|
||||
: test_case(params) {
|
||||
|
@ -13,14 +13,14 @@ public:
|
|||
{
|
||||
throw mapnik::image_reader_exception("Failed to load: " + filename);
|
||||
}
|
||||
im_ = std::make_shared<image_32>(reader->width(),reader->height());
|
||||
reader->read(0,0,im_->data());
|
||||
im_ = std::make_shared<image_rgba8>(reader->width(),reader->height());
|
||||
reader->read(0,0,*im_);
|
||||
}
|
||||
bool validate() const
|
||||
{
|
||||
std::string expected("./benchmark/data/multicolor-hextree-expected.png");
|
||||
std::string actual("./benchmark/data/multicolor-hextree-actual.png");
|
||||
mapnik::save_to_file(im_->data(),actual, "png8:m=h:z=1");
|
||||
mapnik::save_to_file(*im_,actual, "png8:m=h:z=1");
|
||||
return benchmark::compare_images(actual,expected);
|
||||
}
|
||||
bool operator()() const
|
||||
|
@ -28,7 +28,7 @@ public:
|
|||
std::string out;
|
||||
for (std::size_t i=0;i<iterations_;++i) {
|
||||
out.clear();
|
||||
out = mapnik::save_to_string(im_->data(),"png8:m=h:z=1");
|
||||
out = mapnik::save_to_string(*im_,"png8:m=h:z=1");
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/transform_path_adapter.hpp>
|
||||
#include <mapnik/view_transform.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/wkt/wkt_factory.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
@ -37,12 +36,12 @@ void render(mapnik::geometry_type const& geom,
|
|||
using ren_base = agg::renderer_base<agg::pixfmt_rgba32_plain>;
|
||||
using renderer = agg::renderer_scanline_aa_solid<ren_base>;
|
||||
mapnik::vertex_adapter va(geom);
|
||||
mapnik::image_32 im(256,256);
|
||||
im.set_background(mapnik::color("white"));
|
||||
mapnik::image_rgba8 im(256,256);
|
||||
mapnik::fill(im, mapnik::color("white"));
|
||||
mapnik::box2d<double> padded_extent = extent;
|
||||
padded_extent.pad(10);
|
||||
mapnik::view_transform tr(im.width(),im.height(),padded_extent,0,0);
|
||||
agg::rendering_buffer buf(im.raw_data(),im.width(),im.height(), im.width() * 4);
|
||||
agg::rendering_buffer buf(im.getBytes(),im.width(),im.height(), im.getRowSize());
|
||||
agg::pixfmt_rgba32_plain pixf(buf);
|
||||
ren_base renb(pixf);
|
||||
renderer ren(renb);
|
||||
|
@ -53,7 +52,7 @@ void render(mapnik::geometry_type const& geom,
|
|||
ras.add_path(path);
|
||||
agg::scanline_u8 sl;
|
||||
agg::render_scanlines(ras, sl, ren);
|
||||
mapnik::save_to_file(im.data(),name);
|
||||
mapnik::save_to_file(im,name);
|
||||
}
|
||||
|
||||
class test1 : public benchmark::test_case
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "bench_framework.hpp"
|
||||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/load_map.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
|
||||
|
@ -22,8 +21,8 @@ public:
|
|||
mapnik::Map m(256,256);
|
||||
mapnik::load_map(m,xml_);
|
||||
m.zoom_to_box(extent_);
|
||||
mapnik::image_32 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||
mapnik::image_rgba8 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im);
|
||||
ren.apply();
|
||||
//mapnik::save_to_file(im.data(),"test.png");
|
||||
return true;
|
||||
|
@ -35,8 +34,8 @@ public:
|
|||
m.zoom_to_box(extent_);
|
||||
for (unsigned i=0;i<iterations_;++i)
|
||||
{
|
||||
mapnik::image_32 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(m,im);
|
||||
mapnik::image_rgba8 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im);
|
||||
ren.apply();
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/load_map.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
|
@ -55,12 +54,12 @@ public:
|
|||
} else {
|
||||
m.zoom_all();
|
||||
}
|
||||
mapnik::image_32 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(m,im,scale_factor_);
|
||||
mapnik::image_rgba8 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_);
|
||||
ren.apply();
|
||||
if (!preview_.empty()) {
|
||||
std::clog << "preview available at " << preview_ << "\n";
|
||||
mapnik::save_to_file(im.data(),preview_);
|
||||
mapnik::save_to_file(im,preview_);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -78,8 +77,8 @@ public:
|
|||
}
|
||||
for (unsigned i=0;i<iterations_;++i)
|
||||
{
|
||||
mapnik::image_32 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(m,im,scale_factor_);
|
||||
mapnik::image_rgba8 im(m.width(),m.height());
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m,im,scale_factor_);
|
||||
ren.apply();
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include <mapnik/map.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/load_map.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/datasource_cache.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
|
@ -50,7 +49,7 @@ class test : public benchmark::test_case
|
|||
std::shared_ptr<mapnik::Map> m_;
|
||||
double scale_factor_;
|
||||
std::string preview_;
|
||||
mutable mapnik::image_32 im_;
|
||||
mutable mapnik::image_rgba8 im_;
|
||||
public:
|
||||
test(mapnik::parameters const& params)
|
||||
: test_case(params),
|
||||
|
@ -94,14 +93,14 @@ public:
|
|||
mapnik::projection map_proj(m_->srs(),true);
|
||||
double scale_denom = mapnik::scale_denominator(m_req.scale(),map_proj.is_geographic());
|
||||
scale_denom *= scale_factor_;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(*m_,m_req,variables,im_,scale_factor_);
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_,m_req,variables,im_,scale_factor_);
|
||||
ren.start_map_processing(*m_);
|
||||
std::vector<mapnik::layer> const& layers = m_->layers();
|
||||
process_layers(ren,m_req,map_proj,layers,scale_denom);
|
||||
ren.end_map_processing(*m_);
|
||||
if (!preview_.empty()) {
|
||||
std::clog << "preview available at " << preview_ << "\n";
|
||||
mapnik::save_to_file(im_.data(),preview_);
|
||||
mapnik::save_to_file(im_,preview_);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -114,20 +113,20 @@ public:
|
|||
for (unsigned i=0;i<iterations_;++i)
|
||||
{
|
||||
mapnik::request m_req(width_,height_,extent_);
|
||||
mapnik::image_32 im(m_->width(),m_->height());
|
||||
mapnik::image_rgba8 im(m_->width(),m_->height());
|
||||
mapnik::attributes variables;
|
||||
m_req.set_buffer_size(m_->buffer_size());
|
||||
mapnik::projection map_proj(m_->srs(),true);
|
||||
double scale_denom = mapnik::scale_denominator(m_req.scale(),map_proj.is_geographic());
|
||||
scale_denom *= scale_factor_;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(*m_,m_req,variables,im,scale_factor_);
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(*m_,m_req,variables,im,scale_factor_);
|
||||
ren.start_map_processing(*m_);
|
||||
std::vector<mapnik::layer> const& layers = m_->layers();
|
||||
process_layers(ren,m_req,map_proj,layers,scale_denom);
|
||||
ren.end_map_processing(*m_);
|
||||
bool diff = false;
|
||||
mapnik::image_data_rgba8 const& dest = im.data();
|
||||
mapnik::image_data_rgba8 const& src = im_.data();
|
||||
mapnik::image_rgba8 const& dest = im;
|
||||
mapnik::image_rgba8 const& src = im_;
|
||||
for (unsigned int y = 0; y < height_; ++y)
|
||||
{
|
||||
const unsigned int* row_from = src.getRow(y);
|
||||
|
|
|
@ -57,17 +57,39 @@ void export_color ()
|
|||
"and an alpha value.\n"
|
||||
"All values between 0 and 255.\n")
|
||||
)
|
||||
.def(init<int,int,int,int,bool>(
|
||||
( arg("r"), arg("g"), arg("b"), arg("a"), arg("premultiplied") ),
|
||||
"Creates a new color from its RGB components\n"
|
||||
"and an alpha value.\n"
|
||||
"All values between 0 and 255.\n")
|
||||
)
|
||||
.def(init<int,int,int>(
|
||||
( arg("r"), arg("g"), arg("b") ),
|
||||
"Creates a new color from its RGB components.\n"
|
||||
"All values between 0 and 255.\n")
|
||||
)
|
||||
.def(init<uint32_t>(
|
||||
( arg("val") ),
|
||||
"Creates a new color from an unsigned integer.\n"
|
||||
"All values between 0 and 2^32-1\n")
|
||||
)
|
||||
.def(init<uint32_t, bool>(
|
||||
( arg("val"), arg("premultiplied") ),
|
||||
"Creates a new color from an unsigned integer.\n"
|
||||
"All values between 0 and 2^32-1\n")
|
||||
)
|
||||
.def(init<std::string>(
|
||||
( arg("color_string") ),
|
||||
"Creates a new color from its CSS string representation.\n"
|
||||
"The string may be a CSS color name (e.g. 'blue')\n"
|
||||
"or a hex color string (e.g. '#0000ff').\n")
|
||||
)
|
||||
.def(init<std::string, bool>(
|
||||
( arg("color_string"), arg("premultiplied") ),
|
||||
"Creates a new color from its CSS string representation.\n"
|
||||
"The string may be a CSS color name (e.g. 'blue')\n"
|
||||
"or a hex color string (e.g. '#0000ff').\n")
|
||||
)
|
||||
.add_property("r",
|
||||
&color::red,
|
||||
&color::set_red,
|
||||
|
@ -92,6 +114,10 @@ void export_color ()
|
|||
.def(self != self)
|
||||
.def_pickle(color_pickle_suite())
|
||||
.def("__str__",&color::to_string)
|
||||
.def("set_premultiplied",&color::set_premultiplied)
|
||||
.def("get_premultiplied",&color::get_premultiplied)
|
||||
.def("premultiply",&color::premultiply)
|
||||
.def("demultiply",&color::demultiply)
|
||||
.def("packed",&color::rgba)
|
||||
.def("to_hex_string",&color::to_hex_string,
|
||||
"Returns the hexadecimal representation of this color.\n"
|
||||
|
|
|
@ -35,11 +35,13 @@
|
|||
#pragma GCC diagnostic pop
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/palette.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_copy.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
#include <mapnik/image_view_any.hpp>
|
||||
|
||||
// cairo
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
|
@ -49,7 +51,7 @@
|
|||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
using mapnik::image_32;
|
||||
using mapnik::image_any;
|
||||
using mapnik::image_reader;
|
||||
using mapnik::get_image_reader;
|
||||
using mapnik::type_from_filename;
|
||||
|
@ -58,22 +60,21 @@ using mapnik::save_to_file;
|
|||
using namespace boost::python;
|
||||
|
||||
// output 'raw' pixels
|
||||
PyObject* tostring1( image_32 const& im)
|
||||
PyObject* tostring1( image_any const& im)
|
||||
{
|
||||
int size = im.width() * im.height() * 4;
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyBytes_FromStringAndSize
|
||||
#else
|
||||
::PyString_FromStringAndSize
|
||||
#endif
|
||||
((const char*)im.raw_data(),size);
|
||||
((const char*)im.getBytes(),im.getSize());
|
||||
}
|
||||
|
||||
// encode (png,jpeg)
|
||||
PyObject* tostring2(image_32 const & im, std::string const& format)
|
||||
PyObject* tostring2(image_any const & im, std::string const& format)
|
||||
{
|
||||
std::string s = mapnik::save_to_string(im.data(), format);
|
||||
std::string s = mapnik::save_to_string(im, format);
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyBytes_FromStringAndSize
|
||||
|
@ -83,9 +84,9 @@ PyObject* tostring2(image_32 const & im, std::string const& format)
|
|||
(s.data(),s.size());
|
||||
}
|
||||
|
||||
PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
PyObject* tostring3(image_any const & im, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
{
|
||||
std::string s = mapnik::save_to_string(im.data(), format, pal);
|
||||
std::string s = mapnik::save_to_string(im, format, pal);
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyBytes_FromStringAndSize
|
||||
|
@ -96,66 +97,144 @@ PyObject* tostring3(image_32 const & im, std::string const& format, mapnik::rgba
|
|||
}
|
||||
|
||||
|
||||
void save_to_file1(mapnik::image_32 const& im, std::string const& filename)
|
||||
void save_to_file1(mapnik::image_any const& im, std::string const& filename)
|
||||
{
|
||||
save_to_file(im.data(),filename);
|
||||
save_to_file(im,filename);
|
||||
}
|
||||
|
||||
void save_to_file2(mapnik::image_32 const& im, std::string const& filename, std::string const& type)
|
||||
void save_to_file2(mapnik::image_any const& im, std::string const& filename, std::string const& type)
|
||||
{
|
||||
save_to_file(im.data(),filename,type);
|
||||
save_to_file(im,filename,type);
|
||||
}
|
||||
|
||||
void save_to_file3(mapnik::image_32 const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette const& pal)
|
||||
void save_to_file3(mapnik::image_any const& im, std::string const& filename, std::string const& type, mapnik::rgba_palette const& pal)
|
||||
{
|
||||
save_to_file(im.data(),filename,type,pal);
|
||||
save_to_file(im,filename,type,pal);
|
||||
}
|
||||
|
||||
bool painted(mapnik::image_32 const& im)
|
||||
mapnik::image_view_any get_view(mapnik::image_any const& data,unsigned x,unsigned y, unsigned w,unsigned h)
|
||||
{
|
||||
return im.painted();
|
||||
return mapnik::create_view(data,x,y,w,h);
|
||||
}
|
||||
|
||||
bool is_solid(mapnik::image_32 const& im)
|
||||
bool is_solid(mapnik::image_any const& im)
|
||||
{
|
||||
if (im.width() > 0 && im.height() > 0)
|
||||
return mapnik::is_solid(im);
|
||||
}
|
||||
|
||||
void fill_color(mapnik::image_any & im, mapnik::color const& c)
|
||||
{
|
||||
mapnik::fill(im, c);
|
||||
}
|
||||
|
||||
void fill_int(mapnik::image_any & im, int val)
|
||||
{
|
||||
mapnik::fill(im, val);
|
||||
}
|
||||
|
||||
void fill_double(mapnik::image_any & im, double val)
|
||||
{
|
||||
mapnik::fill(im, val);
|
||||
}
|
||||
|
||||
std::shared_ptr<image_any> copy(mapnik::image_any const& im, mapnik::image_dtype type, double offset, double scaling)
|
||||
{
|
||||
return std::make_shared<image_any>(std::move(mapnik::image_copy(im, type, offset, scaling)));
|
||||
}
|
||||
|
||||
unsigned compare(mapnik::image_any const& im1, mapnik::image_any const& im2, double threshold, bool alpha)
|
||||
{
|
||||
return mapnik::compare(im1, im2, threshold, alpha);
|
||||
}
|
||||
|
||||
struct get_pixel_visitor
|
||||
{
|
||||
get_pixel_visitor(unsigned x, unsigned y)
|
||||
: x_(x), y_(y) {}
|
||||
|
||||
PyObject* operator() (mapnik::image_null const&)
|
||||
{
|
||||
mapnik::image_data_rgba8 const & data = im.data();
|
||||
mapnik::image_data_rgba8::pixel_type const* first_row = data.getRow(0);
|
||||
mapnik::image_data_rgba8::pixel_type const first_pixel = first_row[0];
|
||||
for (unsigned y = 0; y < im.height(); ++y)
|
||||
{
|
||||
mapnik::image_data_rgba8::pixel_type const * row = data.getRow(y);
|
||||
for (unsigned x = 0; x < im.width(); ++x)
|
||||
{
|
||||
if (first_pixel != row[x])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw std::runtime_error("Can not return a null image from a pixel (shouldn't have reached here)");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned get_pixel(mapnik::image_32 const& im, int x, int y)
|
||||
{
|
||||
if (x < static_cast<int>(im.width()) && y < static_cast<int>(im.height()))
|
||||
|
||||
PyObject* operator() (mapnik::image_gray32f const& im)
|
||||
{
|
||||
mapnik::image_data_rgba8 const & data = im.data();
|
||||
return data(x,y);
|
||||
return PyFloat_FromDouble(mapnik::get_pixel<double>(im, x_, y_));
|
||||
}
|
||||
|
||||
PyObject* operator() (mapnik::image_gray64f const& im)
|
||||
{
|
||||
return PyFloat_FromDouble(mapnik::get_pixel<double>(im, x_, y_));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
PyObject* operator() (T const& im)
|
||||
{
|
||||
using pixel_type = typename T::pixel_type;
|
||||
return PyInt_FromLong(mapnik::get_pixel<pixel_type>(im, x_, y_));
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned x_;
|
||||
unsigned y_;
|
||||
};
|
||||
|
||||
PyObject* get_pixel(mapnik::image_any const& im, unsigned x, unsigned y)
|
||||
{
|
||||
if (x < static_cast<unsigned>(im.width()) && y < static_cast<unsigned>(im.height()))
|
||||
{
|
||||
return mapnik::util::apply_visitor(get_pixel_visitor(x, y), im);
|
||||
}
|
||||
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
|
||||
boost::python::throw_error_already_set();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void set_pixel(mapnik::image_32 & im, unsigned x, unsigned y, mapnik::color const& c)
|
||||
mapnik::color get_pixel_color(mapnik::image_any const& im, unsigned x, unsigned y)
|
||||
{
|
||||
im.setPixel(x, y, c.rgba());
|
||||
if (x < static_cast<unsigned>(im.width()) && y < static_cast<unsigned>(im.height()))
|
||||
{
|
||||
return mapnik::get_pixel<mapnik::color>(im, x, y);
|
||||
}
|
||||
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
|
||||
boost::python::throw_error_already_set();
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::shared_ptr<image_32> open_from_file(std::string const& filename)
|
||||
void set_pixel_color(mapnik::image_any & im, unsigned x, unsigned y, mapnik::color const& c)
|
||||
{
|
||||
if (x >= static_cast<int>(im.width()) && y >= static_cast<int>(im.height()))
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
|
||||
boost::python::throw_error_already_set();
|
||||
return;
|
||||
}
|
||||
mapnik::set_pixel(im, x, y, c);
|
||||
}
|
||||
|
||||
void set_pixel_double(mapnik::image_any & im, unsigned x, unsigned y, double val)
|
||||
{
|
||||
if (x >= static_cast<int>(im.width()) && y >= static_cast<int>(im.height()))
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
|
||||
boost::python::throw_error_already_set();
|
||||
return;
|
||||
}
|
||||
mapnik::set_pixel(im, x, y, val);
|
||||
}
|
||||
|
||||
void set_pixel_int(mapnik::image_any & im, unsigned x, unsigned y, int val)
|
||||
{
|
||||
if (x >= static_cast<int>(im.width()) && y >= static_cast<int>(im.height()))
|
||||
{
|
||||
PyErr_SetString(PyExc_IndexError, "invalid x,y for image dimensions");
|
||||
boost::python::throw_error_already_set();
|
||||
return;
|
||||
}
|
||||
mapnik::set_pixel(im, x, y, val);
|
||||
}
|
||||
|
||||
std::shared_ptr<image_any> open_from_file(std::string const& filename)
|
||||
{
|
||||
boost::optional<std::string> type = type_from_filename(filename);
|
||||
if (type)
|
||||
|
@ -163,29 +242,24 @@ std::shared_ptr<image_32> open_from_file(std::string const& filename)
|
|||
std::unique_ptr<image_reader> reader(get_image_reader(filename,*type));
|
||||
if (reader.get())
|
||||
{
|
||||
|
||||
std::shared_ptr<image_32> image_ptr = std::make_shared<image_32>(reader->width(),reader->height());
|
||||
reader->read(0,0,image_ptr->data());
|
||||
return image_ptr;
|
||||
return std::make_shared<image_any>(std::move(reader->read(0,0,reader->width(),reader->height())));
|
||||
}
|
||||
throw mapnik::image_reader_exception("Failed to load: " + filename);
|
||||
}
|
||||
throw mapnik::image_reader_exception("Unsupported image format:" + filename);
|
||||
}
|
||||
|
||||
std::shared_ptr<image_32> fromstring(std::string const& str)
|
||||
std::shared_ptr<image_any> fromstring(std::string const& str)
|
||||
{
|
||||
std::unique_ptr<image_reader> reader(get_image_reader(str.c_str(),str.size()));
|
||||
if (reader.get())
|
||||
{
|
||||
std::shared_ptr<image_32> image_ptr = std::make_shared<image_32>(reader->width(),reader->height());
|
||||
reader->read(0,0,image_ptr->data());
|
||||
return image_ptr;
|
||||
return std::make_shared<image_any>(std::move(reader->read(0,0,reader->width(), reader->height())));
|
||||
}
|
||||
throw mapnik::image_reader_exception("Failed to load image from buffer" );
|
||||
}
|
||||
|
||||
std::shared_ptr<image_32> frombuffer(PyObject * obj)
|
||||
std::shared_ptr<image_any> frombuffer(PyObject * obj)
|
||||
{
|
||||
void const* buffer=0;
|
||||
Py_ssize_t buffer_len;
|
||||
|
@ -194,32 +268,74 @@ std::shared_ptr<image_32> frombuffer(PyObject * obj)
|
|||
std::unique_ptr<image_reader> reader(get_image_reader(reinterpret_cast<char const*>(buffer),buffer_len));
|
||||
if (reader.get())
|
||||
{
|
||||
std::shared_ptr<image_32> image_ptr = std::make_shared<image_32>(reader->width(),reader->height());
|
||||
reader->read(0,0,image_ptr->data());
|
||||
return image_ptr;
|
||||
return std::make_shared<image_any>(reader->read(0,0,reader->width(),reader->height()));
|
||||
}
|
||||
}
|
||||
throw mapnik::image_reader_exception("Failed to load image from buffer" );
|
||||
}
|
||||
|
||||
|
||||
void blend (image_32 & im, unsigned x, unsigned y, image_32 const& im2, float opacity)
|
||||
void set_grayscale_to_alpha(image_any & im)
|
||||
{
|
||||
im.set_rectangle_alpha2(im2.data(),x,y,opacity);
|
||||
mapnik::set_grayscale_to_alpha(im);
|
||||
}
|
||||
|
||||
void composite(image_32 & dst, image_32 & src, mapnik::composite_mode_e mode, float opacity)
|
||||
void set_grayscale_to_alpha_c(image_any & im, mapnik::color const& c)
|
||||
{
|
||||
mapnik::composite(dst.data(),src.data(),mode,opacity,0,0,false);
|
||||
mapnik::set_grayscale_to_alpha(im, c);
|
||||
}
|
||||
|
||||
void set_color_to_alpha(image_any & im, mapnik::color const& c)
|
||||
{
|
||||
mapnik::set_color_to_alpha(im, c);
|
||||
}
|
||||
|
||||
void set_alpha(image_any & im, float opacity)
|
||||
{
|
||||
mapnik::set_alpha(im, opacity);
|
||||
}
|
||||
|
||||
bool premultiplied(image_any &im)
|
||||
{
|
||||
return im.get_premultiplied();
|
||||
}
|
||||
|
||||
bool premultiply(image_any & im)
|
||||
{
|
||||
return mapnik::premultiply_alpha(im);
|
||||
}
|
||||
|
||||
bool demultiply(image_any & im)
|
||||
{
|
||||
return mapnik::demultiply_alpha(im);
|
||||
}
|
||||
|
||||
void clear(image_any & im)
|
||||
{
|
||||
mapnik::fill(im, 0);
|
||||
}
|
||||
|
||||
void composite(image_any & dst, image_any & src, mapnik::composite_mode_e mode, float opacity, int dx, int dy)
|
||||
{
|
||||
bool demultiply_dst = mapnik::premultiply_alpha(dst);
|
||||
bool demultiply_src = mapnik::premultiply_alpha(src);
|
||||
mapnik::composite(dst,src,mode,opacity,dx,dy);
|
||||
if (demultiply_dst)
|
||||
{
|
||||
mapnik::demultiply_alpha(dst);
|
||||
}
|
||||
if (demultiply_src)
|
||||
{
|
||||
mapnik::demultiply_alpha(src);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
std::shared_ptr<image_32> from_cairo(PycairoSurface* py_surface)
|
||||
std::shared_ptr<image_any> from_cairo(PycairoSurface* py_surface)
|
||||
{
|
||||
mapnik::cairo_surface_ptr surface(cairo_surface_reference(py_surface->surface), mapnik::cairo_surface_closer());
|
||||
std::shared_ptr<image_32> image_ptr = std::make_shared<image_32>(cairo_image_surface_get_width(&*surface), cairo_image_surface_get_height(&*surface));
|
||||
cairo_image_to_rgba8(image_ptr->data(), surface);
|
||||
return image_ptr;
|
||||
mapnik::image_rgba8 image = mapnik::image_rgba8(cairo_image_surface_get_width(&*surface), cairo_image_surface_get_height(&*surface));
|
||||
cairo_image_to_rgba8(image, surface);
|
||||
return std::make_shared<image_any>(std::move(image));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -266,31 +382,74 @@ void export_image()
|
|||
.value("divide", mapnik::divide)
|
||||
;
|
||||
|
||||
class_<image_32,std::shared_ptr<image_32> >("Image","This class represents a 32 bit RGBA image.",init<int,int>())
|
||||
.def("width",&image_32::width)
|
||||
.def("height",&image_32::height)
|
||||
.def("view",&image_32::get_view)
|
||||
.def("painted",&painted)
|
||||
enum_<mapnik::image_dtype>("ImageType")
|
||||
.value("rgba8", mapnik::image_dtype_rgba8)
|
||||
.value("gray8", mapnik::image_dtype_gray8)
|
||||
.value("gray8s", mapnik::image_dtype_gray8s)
|
||||
.value("gray16", mapnik::image_dtype_gray16)
|
||||
.value("gray16s", mapnik::image_dtype_gray16s)
|
||||
.value("gray32", mapnik::image_dtype_gray32)
|
||||
.value("gray32s", mapnik::image_dtype_gray32s)
|
||||
.value("gray32f", mapnik::image_dtype_gray32f)
|
||||
.value("gray64", mapnik::image_dtype_gray64)
|
||||
.value("gray64s", mapnik::image_dtype_gray64s)
|
||||
.value("gray64f", mapnik::image_dtype_gray64f)
|
||||
;
|
||||
|
||||
class_<image_any,std::shared_ptr<image_any>, boost::noncopyable >("Image","This class represents a image.",init<int,int>())
|
||||
.def(init<int,int,mapnik::image_dtype>())
|
||||
.def(init<int,int,mapnik::image_dtype,bool>())
|
||||
.def(init<int,int,mapnik::image_dtype,bool,bool>())
|
||||
.def(init<int,int,mapnik::image_dtype,bool,bool,bool>())
|
||||
.def("width",&image_any::width)
|
||||
.def("height",&image_any::height)
|
||||
.def("view",&get_view)
|
||||
.def("painted",&image_any::painted)
|
||||
.def("is_solid",&is_solid)
|
||||
.add_property("background",make_function
|
||||
(&image_32::get_background,return_value_policy<copy_const_reference>()),
|
||||
&image_32::set_background, "The background color of the image.")
|
||||
.def("set_grayscale_to_alpha",&image_32::set_grayscale_to_alpha, "Set the grayscale values to the alpha channel of the Image")
|
||||
.def("set_color_to_alpha",&image_32::set_color_to_alpha, "Set a given color to the alpha channel of the Image")
|
||||
.def("set_alpha",&image_32::set_alpha, "Set the overall alpha channel of the Image")
|
||||
.def("blend",&blend)
|
||||
.def("fill",&fill_color)
|
||||
.def("fill",&fill_int)
|
||||
.def("fill",&fill_double)
|
||||
.def("set_grayscale_to_alpha",&set_grayscale_to_alpha, "Set the grayscale values to the alpha channel of the Image")
|
||||
.def("set_grayscale_to_alpha",&set_grayscale_to_alpha_c, "Set the grayscale values to the alpha channel of the Image")
|
||||
.def("set_color_to_alpha",&set_color_to_alpha, "Set a given color to the alpha channel of the Image")
|
||||
.def("set_alpha",&set_alpha, "Set the overall alpha channel of the Image")
|
||||
.def("composite",&composite,
|
||||
( arg("self"),
|
||||
arg("image"),
|
||||
arg("mode")=mapnik::src_over,
|
||||
arg("opacity")=1.0f
|
||||
arg("opacity")=1.0f,
|
||||
arg("dx")=0,
|
||||
arg("dy")=0
|
||||
))
|
||||
.def("premultiplied",&image_32::premultiplied)
|
||||
.def("premultiply",&image_32::premultiply)
|
||||
.def("demultiply",&image_32::demultiply)
|
||||
.def("set_pixel",&set_pixel)
|
||||
.def("compare",&compare,
|
||||
( arg("self"),
|
||||
arg("image"),
|
||||
arg("threshold")=0.0,
|
||||
arg("alpha")=true
|
||||
))
|
||||
.def("copy",©,
|
||||
( arg("self"),
|
||||
arg("type"),
|
||||
arg("offset")=0.0,
|
||||
arg("scaling")=1.0
|
||||
))
|
||||
.add_property("offset",
|
||||
&image_any::get_offset,
|
||||
&image_any::set_offset,
|
||||
"Gets or sets the offset component.\n")
|
||||
.add_property("scaling",
|
||||
&image_any::get_scaling,
|
||||
&image_any::set_scaling,
|
||||
"Gets or sets the offset component.\n")
|
||||
.def("premultiplied",&premultiplied)
|
||||
.def("premultiply",&premultiply)
|
||||
.def("demultiply",&demultiply)
|
||||
.def("set_pixel",&set_pixel_color)
|
||||
.def("set_pixel",&set_pixel_double)
|
||||
.def("set_pixel",&set_pixel_int)
|
||||
.def("get_pixel",&get_pixel)
|
||||
.def("clear",&image_32::clear)
|
||||
.def("get_pixel_color",&get_pixel_color)
|
||||
.def("clear",&clear)
|
||||
//TODO(haoyu) The method name 'tostring' might be confusing since they actually return bytes in Python 3
|
||||
|
||||
.def("tostring",&tostring1)
|
||||
|
|
|
@ -35,26 +35,21 @@
|
|||
#pragma GCC diagnostic pop
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <mapnik/image_view_any.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/palette.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <sstream>
|
||||
|
||||
using mapnik::image_data_rgba8;
|
||||
using mapnik::image_view;
|
||||
using mapnik::image_view_any;
|
||||
using mapnik::save_to_file;
|
||||
|
||||
// output 'raw' pixels
|
||||
PyObject* view_tostring1(image_view<image_data_rgba8> const& view)
|
||||
PyObject* view_tostring1(image_view_any const& view)
|
||||
{
|
||||
std::ostringstream ss(std::ios::out|std::ios::binary);
|
||||
for (unsigned i=0;i<view.height();i++)
|
||||
{
|
||||
ss.write(reinterpret_cast<const char*>(view.getRow(i)),
|
||||
view.width() * sizeof(image_view<image_data_rgba8>::pixel_type));
|
||||
}
|
||||
mapnik::view_to_string(view, ss);
|
||||
return
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
::PyBytes_FromStringAndSize
|
||||
|
@ -65,7 +60,7 @@ PyObject* view_tostring1(image_view<image_data_rgba8> const& view)
|
|||
}
|
||||
|
||||
// encode (png,jpeg)
|
||||
PyObject* view_tostring2(image_view<image_data_rgba8> const & view, std::string const& format)
|
||||
PyObject* view_tostring2(image_view_any const & view, std::string const& format)
|
||||
{
|
||||
std::string s = save_to_string(view, format);
|
||||
return
|
||||
|
@ -77,7 +72,7 @@ PyObject* view_tostring2(image_view<image_data_rgba8> const & view, std::string
|
|||
(s.data(),s.size());
|
||||
}
|
||||
|
||||
PyObject* view_tostring3(image_view<image_data_rgba8> const & view, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
PyObject* view_tostring3(image_view_any const & view, std::string const& format, mapnik::rgba_palette const& pal)
|
||||
{
|
||||
std::string s = save_to_string(view, format, pal);
|
||||
return
|
||||
|
@ -89,41 +84,25 @@ PyObject* view_tostring3(image_view<image_data_rgba8> const & view, std::string
|
|||
(s.data(),s.size());
|
||||
}
|
||||
|
||||
bool is_solid(image_view<image_data_rgba8> const& view)
|
||||
bool is_solid(image_view_any const& view)
|
||||
{
|
||||
if (view.width() > 0 && view.height() > 0)
|
||||
{
|
||||
mapnik::image_view<image_data_rgba8>::pixel_type const* first_row = view.getRow(0);
|
||||
mapnik::image_view<image_data_rgba8>::pixel_type const first_pixel = first_row[0];
|
||||
for (unsigned y = 0; y < view.height(); ++y)
|
||||
{
|
||||
mapnik::image_view<image_data_rgba8>::pixel_type const * row = view.getRow(y);
|
||||
for (unsigned x = 0; x < view.width(); ++x)
|
||||
{
|
||||
if (first_pixel != row[x])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return mapnik::is_solid(view);
|
||||
}
|
||||
|
||||
void save_view1(image_view<image_data_rgba8> const& view,
|
||||
void save_view1(image_view_any const& view,
|
||||
std::string const& filename)
|
||||
{
|
||||
save_to_file(view,filename);
|
||||
}
|
||||
|
||||
void save_view2(image_view<image_data_rgba8> const& view,
|
||||
void save_view2(image_view_any const& view,
|
||||
std::string const& filename,
|
||||
std::string const& type)
|
||||
{
|
||||
save_to_file(view,filename,type);
|
||||
}
|
||||
|
||||
void save_view3(image_view<image_data_rgba8> const& view,
|
||||
void save_view3(image_view_any const& view,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
mapnik::rgba_palette const& pal)
|
||||
|
@ -135,9 +114,9 @@ void save_view3(image_view<image_data_rgba8> const& view,
|
|||
void export_image_view()
|
||||
{
|
||||
using namespace boost::python;
|
||||
class_<image_view<image_data_rgba8> >("ImageView","A view into an image.",no_init)
|
||||
.def("width",&image_view<image_data_rgba8>::width)
|
||||
.def("height",&image_view<image_data_rgba8>::height)
|
||||
class_<image_view_any>("ImageView","A view into an image.",no_init)
|
||||
.def("width",&image_view_any::width)
|
||||
.def("height",&image_view_any::height)
|
||||
.def("is_solid",&is_solid)
|
||||
.def("tostring",&view_tostring1)
|
||||
.def("tostring",&view_tostring2)
|
||||
|
|
|
@ -99,9 +99,9 @@ void export_logger();
|
|||
#include <mapnik/datasource.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/load_map.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/save_map.hpp>
|
||||
|
@ -136,12 +136,16 @@ void clear_cache()
|
|||
#endif
|
||||
}
|
||||
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
#if defined(HAVE_CAIRO)
|
||||
#include <mapnik/cairo_io.hpp>
|
||||
#include <mapnik/cairo/cairo_renderer.hpp>
|
||||
#include <cairo.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_PYCAIRO)
|
||||
#include <boost/python/type_id.hpp>
|
||||
#include <boost/python/converter/registry.hpp>
|
||||
#include <pycairo.h>
|
||||
#include <cairo.h>
|
||||
static Pycairo_CAPI_t *Pycairo_CAPI;
|
||||
static void *extract_surface(PyObject* op)
|
||||
{
|
||||
|
@ -188,19 +192,129 @@ bool python_thread::thread_support = true;
|
|||
#endif
|
||||
boost::thread_specific_ptr<PyThreadState> python_thread::state;
|
||||
|
||||
struct agg_renderer_visitor_1
|
||||
{
|
||||
agg_renderer_visitor_1(mapnik::Map const& m, double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||
: m_(m), scale_factor_(scale_factor), offset_x_(offset_x), offset_y_(offset_y) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T & pixmap)
|
||||
{
|
||||
throw std::runtime_error("This image type is not currently supported for rendering.");
|
||||
}
|
||||
|
||||
private:
|
||||
mapnik::Map const& m_;
|
||||
double scale_factor_;
|
||||
unsigned offset_x_;
|
||||
unsigned offset_y_;
|
||||
};
|
||||
|
||||
template <>
|
||||
void agg_renderer_visitor_1::operator()<mapnik::image_rgba8> (mapnik::image_rgba8 & pixmap)
|
||||
{
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m_,pixmap,scale_factor_,offset_x_, offset_y_);
|
||||
ren.apply();
|
||||
}
|
||||
|
||||
struct agg_renderer_visitor_2
|
||||
{
|
||||
agg_renderer_visitor_2(mapnik::Map const &m, std::shared_ptr<mapnik::label_collision_detector4> detector,
|
||||
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||
: m_(m), detector_(detector), scale_factor_(scale_factor), offset_x_(offset_x), offset_y_(offset_y) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T & pixmap)
|
||||
{
|
||||
throw std::runtime_error("This image type is not currently supported for rendering.");
|
||||
}
|
||||
|
||||
private:
|
||||
mapnik::Map const& m_;
|
||||
std::shared_ptr<mapnik::label_collision_detector4> detector_;
|
||||
double scale_factor_;
|
||||
unsigned offset_x_;
|
||||
unsigned offset_y_;
|
||||
};
|
||||
|
||||
template <>
|
||||
void agg_renderer_visitor_2::operator()<mapnik::image_rgba8> (mapnik::image_rgba8 & pixmap)
|
||||
{
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m_,pixmap,detector_, scale_factor_,offset_x_, offset_y_);
|
||||
ren.apply();
|
||||
}
|
||||
|
||||
struct agg_renderer_visitor_3
|
||||
{
|
||||
agg_renderer_visitor_3(mapnik::Map const& m, mapnik::request const& req, mapnik::attributes const& vars,
|
||||
double scale_factor, unsigned offset_x, unsigned offset_y)
|
||||
: m_(m), req_(req), vars_(vars), scale_factor_(scale_factor), offset_x_(offset_x), offset_y_(offset_y) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T & pixmap)
|
||||
{
|
||||
throw std::runtime_error("This image type is not currently supported for rendering.");
|
||||
}
|
||||
|
||||
private:
|
||||
mapnik::Map const& m_;
|
||||
mapnik::request const& req_;
|
||||
mapnik::attributes const& vars_;
|
||||
double scale_factor_;
|
||||
unsigned offset_x_;
|
||||
unsigned offset_y_;
|
||||
|
||||
};
|
||||
|
||||
template <>
|
||||
void agg_renderer_visitor_3::operator()<mapnik::image_rgba8> (mapnik::image_rgba8 & pixmap)
|
||||
{
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m_,req_, vars_, pixmap, scale_factor_, offset_x_, offset_y_);
|
||||
ren.apply();
|
||||
}
|
||||
|
||||
struct agg_renderer_visitor_4
|
||||
{
|
||||
agg_renderer_visitor_4(mapnik::Map const& m, double scale_factor, unsigned offset_x, unsigned offset_y,
|
||||
mapnik::layer const& layer, std::set<std::string>& names)
|
||||
: m_(m), scale_factor_(scale_factor), offset_x_(offset_x), offset_y_(offset_y),
|
||||
layer_(layer), names_(names) {}
|
||||
|
||||
template <typename T>
|
||||
void operator() (T & pixmap)
|
||||
{
|
||||
throw std::runtime_error("This image type is not currently supported for rendering.");
|
||||
}
|
||||
|
||||
private:
|
||||
mapnik::Map const& m_;
|
||||
double scale_factor_;
|
||||
unsigned offset_x_;
|
||||
unsigned offset_y_;
|
||||
mapnik::layer const& layer_;
|
||||
std::set<std::string> & names_;
|
||||
};
|
||||
|
||||
template <>
|
||||
void agg_renderer_visitor_4::operator()<mapnik::image_rgba8> (mapnik::image_rgba8 & pixmap)
|
||||
{
|
||||
mapnik::agg_renderer<mapnik::image_rgba8> ren(m_,pixmap,scale_factor_,offset_x_, offset_y_);
|
||||
ren.apply(layer_, names_);
|
||||
}
|
||||
|
||||
|
||||
void render(mapnik::Map const& map,
|
||||
mapnik::image_32& image,
|
||||
mapnik::image_any& image,
|
||||
double scale_factor = 1.0,
|
||||
unsigned offset_x = 0u,
|
||||
unsigned offset_y = 0u)
|
||||
{
|
||||
python_unblock_auto_block b;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,scale_factor,offset_x, offset_y);
|
||||
ren.apply();
|
||||
mapnik::util::apply_visitor(agg_renderer_visitor_1(map, scale_factor, offset_x, offset_y), image);
|
||||
}
|
||||
|
||||
void render_with_vars(mapnik::Map const& map,
|
||||
mapnik::image_32& image,
|
||||
mapnik::image_any& image,
|
||||
boost::python::dict const& d,
|
||||
double scale_factor = 1.0,
|
||||
unsigned offset_x = 0u,
|
||||
|
@ -210,25 +324,23 @@ void render_with_vars(mapnik::Map const& map,
|
|||
mapnik::request req(map.width(),map.height(),map.get_current_extent());
|
||||
req.set_buffer_size(map.buffer_size());
|
||||
python_unblock_auto_block b;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,req,vars,image,scale_factor,offset_x,offset_y);
|
||||
ren.apply();
|
||||
mapnik::util::apply_visitor(agg_renderer_visitor_3(map, req, vars, scale_factor, offset_x, offset_y), image);
|
||||
}
|
||||
|
||||
void render_with_detector(
|
||||
mapnik::Map const& map,
|
||||
mapnik::image_32 &image,
|
||||
mapnik::image_any &image,
|
||||
std::shared_ptr<mapnik::label_collision_detector4> detector,
|
||||
double scale_factor = 1.0,
|
||||
unsigned offset_x = 0u,
|
||||
unsigned offset_y = 0u)
|
||||
{
|
||||
python_unblock_auto_block b;
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,detector,scale_factor,offset_x,offset_y);
|
||||
ren.apply();
|
||||
mapnik::util::apply_visitor(agg_renderer_visitor_2(map, detector, scale_factor, offset_x, offset_y), image);
|
||||
}
|
||||
|
||||
void render_layer2(mapnik::Map const& map,
|
||||
mapnik::image_32& image,
|
||||
mapnik::image_any& image,
|
||||
unsigned layer_idx,
|
||||
double scale_factor,
|
||||
unsigned offset_x,
|
||||
|
@ -245,9 +357,8 @@ void render_layer2(mapnik::Map const& map,
|
|||
|
||||
python_unblock_auto_block b;
|
||||
mapnik::layer const& layer = layers[layer_idx];
|
||||
mapnik::agg_renderer<mapnik::image_32> ren(map,image,scale_factor,offset_x,offset_y);
|
||||
std::set<std::string> names;
|
||||
ren.apply(layer,names);
|
||||
mapnik::util::apply_visitor(agg_renderer_visitor_4(map, scale_factor, offset_x, offset_y, layer, names), image);
|
||||
}
|
||||
|
||||
#if defined(HAVE_CAIRO) && defined(HAVE_PYCAIRO)
|
||||
|
@ -350,9 +461,9 @@ void render_tile_to_file(mapnik::Map const& map,
|
|||
std::string const& file,
|
||||
std::string const& format)
|
||||
{
|
||||
mapnik::image_32 image(width,height);
|
||||
mapnik::image_any image(width,height);
|
||||
render(map,image,1.0,offset_x, offset_y);
|
||||
mapnik::save_to_file(image.data(),file,format);
|
||||
mapnik::save_to_file(image,file,format);
|
||||
}
|
||||
|
||||
void render_to_file1(mapnik::Map const& map,
|
||||
|
@ -385,9 +496,9 @@ void render_to_file1(mapnik::Map const& map,
|
|||
}
|
||||
else
|
||||
{
|
||||
mapnik::image_32 image(map.width(),map.height());
|
||||
mapnik::image_any image(map.width(),map.height());
|
||||
render(map,image,1.0,0,0);
|
||||
mapnik::save_to_file(image.data(),filename,format);
|
||||
mapnik::save_to_file(image,filename,format);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -404,9 +515,9 @@ void render_to_file2(mapnik::Map const& map,std::string const& filename)
|
|||
}
|
||||
else
|
||||
{
|
||||
mapnik::image_32 image(map.width(),map.height());
|
||||
mapnik::image_any image(map.width(),map.height());
|
||||
render(map,image,1.0,0,0);
|
||||
mapnik::save_to_file(image.data(),filename);
|
||||
mapnik::save_to_file(image,filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -442,9 +553,9 @@ void render_to_file3(mapnik::Map const& map,
|
|||
}
|
||||
else
|
||||
{
|
||||
mapnik::image_32 image(map.width(),map.height());
|
||||
mapnik::image_any image(map.width(),map.height());
|
||||
render(map,image,scale_factor,0,0);
|
||||
mapnik::save_to_file(image.data(),filename,format);
|
||||
mapnik::save_to_file(image,filename,format);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -724,7 +835,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
|
||||
def("render", &render, render_overloads(
|
||||
"\n"
|
||||
"Render Map to an AGG image_32 using offsets\n"
|
||||
"Render Map to an AGG image_any using offsets\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
">>> from mapnik import Map, Image, render, load_map\n"
|
||||
|
@ -741,7 +852,7 @@ BOOST_PYTHON_MODULE(_mapnik)
|
|||
|
||||
def("render_with_detector", &render_with_detector, render_with_detector_overloads(
|
||||
"\n"
|
||||
"Render Map to an AGG image_32 using a pre-constructed detector.\n"
|
||||
"Render Map to an AGG image_any using a pre-constructed detector.\n"
|
||||
"\n"
|
||||
"Usage:\n"
|
||||
">>> from mapnik import Map, Image, LabelCollisionDetector, render_with_detector, load_map\n"
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include <mapnik/path_expression.hpp>
|
||||
#include "mapnik_enumeration.hpp"
|
||||
#include "mapnik_svg.hpp"
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/expression_node.hpp>
|
||||
#include <mapnik/value_error.hpp>
|
||||
#include <mapnik/marker_cache.hpp> // for known_svg_prefix_
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/feature_type_style.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/text/placements/dummy.hpp>
|
||||
#include <mapnik/text/text_properties.hpp>
|
||||
|
@ -37,6 +36,7 @@
|
|||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/unicode.hpp>
|
||||
#include <mapnik/save_map.hpp>
|
||||
#include <mapnik/cairo_io.hpp>
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
#include <mapnik/cairo/cairo_renderer.hpp>
|
||||
|
@ -305,26 +305,26 @@ int main ( int, char** )
|
|||
|
||||
m.zoom_to_box(box2d<double>(-8024477.28459,5445190.38849,-7381388.20071,5662941.44855));
|
||||
|
||||
image_32 buf(m.width(),m.height());
|
||||
agg_renderer<image_32> ren(m,buf);
|
||||
image_rgba8 buf(m.width(),m.height());
|
||||
agg_renderer<image_rgba8> ren(m,buf);
|
||||
ren.apply();
|
||||
std::string msg("These maps have been rendered using AGG in the current directory:\n");
|
||||
#ifdef HAVE_JPEG
|
||||
save_to_file(buf.data(),"demo.jpg","jpeg");
|
||||
save_to_file(buf,"demo.jpg","jpeg");
|
||||
msg += "- demo.jpg\n";
|
||||
#endif
|
||||
#ifdef HAVE_PNG
|
||||
save_to_file(buf.data(),"demo.png","png");
|
||||
save_to_file(buf.data(),"demo256.png","png8");
|
||||
save_to_file(buf,"demo.png","png");
|
||||
save_to_file(buf,"demo256.png","png8");
|
||||
msg += "- demo.png\n";
|
||||
msg += "- demo256.png\n";
|
||||
#endif
|
||||
#ifdef HAVE_TIFF
|
||||
save_to_file(buf.data(),"demo.tif","tiff");
|
||||
save_to_file(buf,"demo.tif","tiff");
|
||||
msg += "- demo.tif\n";
|
||||
#endif
|
||||
#ifdef HAVE_WEBP
|
||||
save_to_file(buf.data(),"demo.webp","webp");
|
||||
save_to_file(buf,"demo.webp","webp");
|
||||
msg += "- demo.webp\n";
|
||||
#endif
|
||||
msg += "Have a look!\n";
|
||||
|
@ -353,7 +353,7 @@ int main ( int, char** )
|
|||
cairo_surface_write_to_png(&*image_surface, "cairo-demo.png");
|
||||
// but we can also benefit from quantization by converting
|
||||
// to a mapnik image object and then saving that
|
||||
mapnik::image_data_rgba8 im_data(cairo_image_surface_get_width(&*image_surface), cairo_image_surface_get_height(&*image_surface));
|
||||
mapnik::image_rgba8 im_data(cairo_image_surface_get_width(&*image_surface), cairo_image_surface_get_height(&*image_surface));
|
||||
cairo_image_to_rgba8(im_data, image_surface);
|
||||
save_to_file(im_data, "cairo-demo256.png","png8");
|
||||
cairo_surface_finish(&*image_surface);
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <boost/bind.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
#include <mapnik/projection.hpp>
|
||||
#include <mapnik/scale_denominator.hpp>
|
||||
|
@ -42,7 +41,7 @@
|
|||
#include "mapwidget.hpp"
|
||||
#include "info_dialog.hpp"
|
||||
|
||||
using mapnik::image_32;
|
||||
using mapnik::image_rgba8;
|
||||
using mapnik::Map;
|
||||
using mapnik::layer;
|
||||
using mapnik::box2d;
|
||||
|
@ -480,7 +479,7 @@ void MapWidget::zoomToLevel(int level)
|
|||
|
||||
void MapWidget::export_to_file(unsigned ,unsigned ,std::string const&,std::string const&)
|
||||
{
|
||||
//image_32 image(width,height);
|
||||
//image_rgba8 image(width,height);
|
||||
//agg_renderer renderer(map,image);
|
||||
//renderer.apply();
|
||||
//image.saveToFile(filename,type);
|
||||
|
@ -497,8 +496,8 @@ void render_agg(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
|||
unsigned width=map.width();
|
||||
unsigned height=map.height();
|
||||
|
||||
image_32 buf(width,height);
|
||||
mapnik::agg_renderer<image_32> ren(map,buf,scaling_factor);
|
||||
image_rgba8 buf(width,height);
|
||||
mapnik::agg_renderer<image_rgba8> ren(map,buf,scaling_factor);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -541,10 +540,9 @@ void render_cairo(mapnik::Map const& map, double scaling_factor, QPixmap & pix)
|
|||
mapnik::cairo_renderer<mapnik::cairo_ptr> renderer(map, cairo, scaling_factor);
|
||||
renderer.apply();
|
||||
}
|
||||
mapnik::image_data_rgba8 data(map.width(), map.height());
|
||||
mapnik::image_rgba8 data(map.width(), map.height());
|
||||
mapnik::cairo_image_to_rgba8(data, image_surface);
|
||||
image_32 buf(std::move(data));
|
||||
QImage image((uchar*)buf.raw_data(),buf.width(),buf.height(),QImage::Format_ARGB32);
|
||||
QImage image((uchar*)data.getBytes(),data.width(),data.height(),QImage::Format_ARGB32);
|
||||
pix = QPixmap::fromImage(image.rgbSwapped());
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -201,7 +201,7 @@ struct symbolizer_icon
|
|||
{
|
||||
// FIXME!
|
||||
/*
|
||||
std::shared_ptr<mapnik::image_data_rgba8> symbol = sym.get_image();
|
||||
std::shared_ptr<mapnik::image_rgba8> symbol = sym.get_image();
|
||||
if (symbol)
|
||||
{
|
||||
QImage image(symbol->getBytes(),
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_AGG_PATTERN_SOURCE_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
|
||||
// agg
|
||||
|
@ -36,7 +36,7 @@ namespace mapnik
|
|||
class pattern_source : private util::noncopyable
|
||||
{
|
||||
public:
|
||||
pattern_source(image_data_rgba8 const& pattern, double opacity = 1.0)
|
||||
pattern_source(image_rgba8 const& pattern, double opacity = 1.0)
|
||||
: pattern_(pattern),
|
||||
opacity_(opacity) {}
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
|||
static_cast<unsigned>(((c >> 24) & 0xff) * opacity_));
|
||||
}
|
||||
private:
|
||||
image_data_rgba8 const& pattern_;
|
||||
image_rgba8 const& pattern_;
|
||||
double opacity_;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ void render_vector_marker(SvgRenderer & svg_renderer, RasterizerType & ras, Rend
|
|||
}
|
||||
|
||||
template <typename RendererType, typename RasterizerType>
|
||||
void render_raster_marker(RendererType renb, RasterizerType & ras, image_data_rgba8 const& src,
|
||||
void render_raster_marker(RendererType renb, RasterizerType & ras, image_rgba8 const& src,
|
||||
agg::trans_affine const& tr, double opacity,
|
||||
float scale_factor, bool snap_to_pixels)
|
||||
{
|
||||
|
@ -81,7 +81,7 @@ void render_raster_marker(RendererType renb, RasterizerType & ras, image_data_rg
|
|||
&& (std::fabs(0.0 - tr.shx) < agg::affine_epsilon)
|
||||
&& (std::fabs(1.0 - tr.sy) < agg::affine_epsilon))
|
||||
{
|
||||
agg::rendering_buffer src_buffer((unsigned char *)src.getBytes(),src.width(),src.height(),src.width() * 4);
|
||||
agg::rendering_buffer src_buffer((unsigned char *)src.getBytes(),src.width(),src.height(),src.getRowSize());
|
||||
pixfmt_pre pixf_mask(src_buffer);
|
||||
if (snap_to_pixels)
|
||||
{
|
||||
|
@ -125,7 +125,7 @@ void render_raster_marker(RendererType renb, RasterizerType & ras, image_data_rg
|
|||
agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(),
|
||||
src.width(),
|
||||
src.height(),
|
||||
src.width()*4);
|
||||
src.getRowSize());
|
||||
pixfmt_pre pixf(marker_buf);
|
||||
img_accessor_type ia(pixf);
|
||||
agg::trans_affine final_tr(p, 0, 0, width, height);
|
||||
|
|
|
@ -36,7 +36,8 @@
|
|||
#include <mapnik/request.hpp>
|
||||
#include <mapnik/symbolizer_enumerations.hpp>
|
||||
#include <mapnik/renderer_common.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
// stl
|
||||
#include <memory>
|
||||
|
||||
|
@ -50,10 +51,9 @@ namespace mapnik {
|
|||
class feature_type_style;
|
||||
class label_collision_detector4;
|
||||
class layer;
|
||||
class marker;
|
||||
struct marker;
|
||||
class proj_transform;
|
||||
struct rasterizer;
|
||||
class image_32;
|
||||
}
|
||||
|
||||
namespace mapnik {
|
||||
|
@ -171,7 +171,7 @@ private:
|
|||
void setup(Map const& m);
|
||||
};
|
||||
|
||||
extern template class MAPNIK_DECL agg_renderer<image_32>;
|
||||
extern template class MAPNIK_DECL agg_renderer<image_rgba8>;
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
|
|
|
@ -27,7 +27,8 @@
|
|||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
#include <mapnik/font_engine_freetype.hpp>
|
||||
#include <mapnik/gradient.hpp>
|
||||
|
@ -121,7 +122,7 @@ private:
|
|||
class cairo_pattern : private util::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit cairo_pattern(image_data_rgba8 const& data, double opacity = 1.0)
|
||||
explicit cairo_pattern(image_rgba8 const& data, double opacity = 1.0)
|
||||
{
|
||||
int pixels = data.width() * data.height();
|
||||
const unsigned int *in_ptr = data.getData();
|
||||
|
@ -279,7 +280,6 @@ inline cairo_ptr create_context(cairo_surface_ptr const& surface)
|
|||
class cairo_context : private util::noncopyable
|
||||
{
|
||||
public:
|
||||
|
||||
cairo_context(cairo_ptr const& cairo);
|
||||
|
||||
inline ErrorStatus get_status() const
|
||||
|
@ -308,8 +308,8 @@ public:
|
|||
void paint();
|
||||
void set_pattern(cairo_pattern const& pattern);
|
||||
void set_gradient(cairo_gradient const& pattern, box2d<double> const& bbox);
|
||||
void add_image(double x, double y, image_data_rgba8 & data, double opacity = 1.0);
|
||||
void add_image(agg::trans_affine const& tr, image_data_rgba8 & data, double opacity = 1.0);
|
||||
void add_image(double x, double y, image_rgba8 const& data, double opacity = 1.0);
|
||||
void add_image(agg::trans_affine const& tr, image_rgba8 const& data, double opacity = 1.0);
|
||||
void set_font_face(cairo_face_manager & manager, face_ptr face);
|
||||
void set_font_matrix(cairo_matrix_t const& matrix);
|
||||
void set_matrix(cairo_matrix_t const& matrix);
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#define MAPNIK_CAIRO_IMAGE_UTIL_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/cairo/cairo_context.hpp> // for cairo_surface_ptr
|
||||
|
||||
// stl
|
||||
|
@ -33,7 +33,7 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
static inline void cairo_image_to_rgba8(mapnik::image_data_rgba8 & data,
|
||||
static inline void cairo_image_to_rgba8(mapnik::image_rgba8 & data,
|
||||
cairo_surface_ptr const& surface)
|
||||
{
|
||||
if (cairo_image_surface_get_format(&*surface) != CAIRO_FORMAT_ARGB32)
|
||||
|
|
|
@ -47,7 +47,7 @@ class feature_impl;
|
|||
class feature_type_style;
|
||||
class label_collision_detector4;
|
||||
class layer;
|
||||
class marker;
|
||||
struct marker;
|
||||
class proj_transform;
|
||||
class request;
|
||||
struct pixel_position;
|
||||
|
@ -165,7 +165,7 @@ public:
|
|||
{
|
||||
return common_.vars_;
|
||||
}
|
||||
|
||||
|
||||
void render_marker(pixel_position const& pos,
|
||||
marker const& marker,
|
||||
agg::trans_affine const& mtx,
|
||||
|
|
49
include/mapnik/cairo_io.hpp
Normal file
49
include/mapnik/cairo_io.hpp
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_CAIRO_IO_HPP
|
||||
#define MAPNIK_CAIRO_IO_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
|
||||
std::string const& filename,
|
||||
double scale_factor=1.0,
|
||||
double scale_denominator=0.0);
|
||||
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
double scale_factor=1.0,
|
||||
double scale_denominator=0.0);
|
||||
#endif
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_CAIRO_IO_HPP
|
|
@ -44,29 +44,39 @@ private:
|
|||
std::uint8_t green_;
|
||||
std::uint8_t blue_;
|
||||
std::uint8_t alpha_;
|
||||
|
||||
bool premultiplied_;
|
||||
public:
|
||||
// default ctor
|
||||
color()
|
||||
: red_(0xff),
|
||||
green_(0xff),
|
||||
blue_(0xff),
|
||||
alpha_(0xff)
|
||||
alpha_(0xff),
|
||||
premultiplied_(false)
|
||||
{}
|
||||
|
||||
color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha = 0xff)
|
||||
color(std::uint8_t red, std::uint8_t green, std::uint8_t blue, std::uint8_t alpha = 0xff, bool premultiplied = false)
|
||||
: red_(red),
|
||||
green_(green),
|
||||
blue_(blue),
|
||||
alpha_(alpha)
|
||||
alpha_(alpha),
|
||||
premultiplied_(premultiplied)
|
||||
{}
|
||||
|
||||
color(std::uint32_t rgba, bool premultiplied = false)
|
||||
: red_(rgba & 0xff),
|
||||
green_((rgba >> 8) & 0xff),
|
||||
blue_((rgba >> 16) & 0xff),
|
||||
alpha_((rgba >> 24) & 0xff),
|
||||
premultiplied_(premultiplied) {}
|
||||
|
||||
// copy ctor
|
||||
color(const color& rhs)
|
||||
: red_(rhs.red_),
|
||||
green_(rhs.green_),
|
||||
blue_(rhs.blue_),
|
||||
alpha_(rhs.alpha_)
|
||||
alpha_(rhs.alpha_),
|
||||
premultiplied_(rhs.premultiplied_)
|
||||
{}
|
||||
|
||||
// move ctor
|
||||
|
@ -74,14 +84,15 @@ public:
|
|||
: red_(std::move(rhs.red_)),
|
||||
green_(std::move(rhs.green_)),
|
||||
blue_(std::move(rhs.blue_)),
|
||||
alpha_(std::move(rhs.alpha_)) {}
|
||||
alpha_(std::move(rhs.alpha_)),
|
||||
premultiplied_(std::move(rhs.premultiplied_)) {}
|
||||
|
||||
color( std::string const& str);
|
||||
color( std::string const& str, bool premultiplied = false);
|
||||
|
||||
std::string to_string() const;
|
||||
std::string to_hex_string() const;
|
||||
void premultiply();
|
||||
void demultiply();
|
||||
bool premultiply();
|
||||
bool demultiply();
|
||||
|
||||
color& operator=(color rhs)
|
||||
{
|
||||
|
@ -135,6 +146,14 @@ public:
|
|||
{
|
||||
alpha_ = alpha;
|
||||
}
|
||||
inline bool get_premultiplied() const
|
||||
{
|
||||
return premultiplied_;
|
||||
}
|
||||
inline void set_premultiplied(bool status)
|
||||
{
|
||||
premultiplied_ = status;
|
||||
}
|
||||
|
||||
inline unsigned rgba() const
|
||||
{
|
||||
|
|
|
@ -1,304 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_GRAPHICS_HPP
|
||||
#define MAPNIK_GRAPHICS_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
// stl
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
// boost
|
||||
#include <boost/optional/optional.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
class MAPNIK_DECL image_32
|
||||
{
|
||||
private:
|
||||
image_data_rgba8 data_;
|
||||
boost::optional<color> background_;
|
||||
bool painted_;
|
||||
bool premultiplied_;
|
||||
public:
|
||||
image_32(int width,int height);
|
||||
image_32(image_32 const& rhs);
|
||||
image_32(image_data_rgba8 && data);
|
||||
~image_32();
|
||||
|
||||
void painted(bool painted)
|
||||
{
|
||||
painted_ = painted;
|
||||
}
|
||||
|
||||
bool painted() const
|
||||
{
|
||||
return painted_;
|
||||
}
|
||||
|
||||
bool premultiplied() const
|
||||
{
|
||||
return premultiplied_;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
std::fill(data_.getData(), data_.getData() + data_.width() * data_.height(), 0);
|
||||
}
|
||||
|
||||
boost::optional<color> const& get_background() const;
|
||||
|
||||
void set_background(const color& c);
|
||||
|
||||
void premultiply();
|
||||
|
||||
void demultiply();
|
||||
|
||||
void set_grayscale_to_alpha();
|
||||
|
||||
void set_color_to_alpha(color const& c);
|
||||
|
||||
void set_alpha(float opacity);
|
||||
|
||||
inline const image_data_rgba8& data() const
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
inline image_data_rgba8& data()
|
||||
{
|
||||
return data_;
|
||||
}
|
||||
|
||||
inline const unsigned char* raw_data() const
|
||||
{
|
||||
return data_.getBytes();
|
||||
}
|
||||
|
||||
inline unsigned char* raw_data()
|
||||
{
|
||||
return data_.getBytes();
|
||||
}
|
||||
|
||||
inline image_view<image_data_rgba8> get_view(unsigned x,unsigned y, unsigned w,unsigned h)
|
||||
{
|
||||
return image_view<image_data_rgba8>(x,y,w,h,data_);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
inline bool checkBounds(int x, int y) const
|
||||
{
|
||||
return (x >= 0 && x < static_cast<int>(data_.width()) && y >= 0 && y < static_cast<int>(data_.height()));
|
||||
}
|
||||
|
||||
public:
|
||||
inline void setPixel(int x,int y,unsigned int rgba)
|
||||
{
|
||||
if (checkBounds(x,y))
|
||||
{
|
||||
data_(x,y)=rgba;
|
||||
}
|
||||
}
|
||||
|
||||
void composite_pixel(unsigned op, int x,int y,unsigned c, unsigned cover, double opacity);
|
||||
|
||||
inline unsigned width() const
|
||||
{
|
||||
return data_.width();
|
||||
}
|
||||
|
||||
inline unsigned height() const
|
||||
{
|
||||
return data_.height();
|
||||
}
|
||||
|
||||
inline void set_rectangle(int x0,int y0,image_data_rgba8 const& data)
|
||||
{
|
||||
box2d<int> ext0(0,0,data_.width(),data_.height());
|
||||
box2d<int> ext1(x0,y0,x0+data.width(),y0+data.height());
|
||||
|
||||
if (ext0.intersects(ext1))
|
||||
{
|
||||
box2d<int> box = ext0.intersect(ext1);
|
||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||
{
|
||||
unsigned int* row_to = data_.getRow(y);
|
||||
unsigned int const * row_from = data.getRow(y-y0);
|
||||
|
||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||
{
|
||||
if (row_from[x-x0] & 0xff000000)
|
||||
{
|
||||
row_to[x] = row_from[x-x0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_rectangle_alpha(int x0,int y0,const image_data_rgba8& data)
|
||||
{
|
||||
box2d<int> ext0(0,0,data_.width(),data_.height());
|
||||
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||
|
||||
if (ext0.intersects(ext1))
|
||||
{
|
||||
box2d<int> box = ext0.intersect(ext1);
|
||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||
{
|
||||
unsigned int* row_to = data_.getRow(y);
|
||||
unsigned int const * row_from = data.getRow(y-y0);
|
||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||
{
|
||||
unsigned rgba0 = row_to[x];
|
||||
unsigned rgba1 = row_from[x-x0];
|
||||
unsigned a1 = (rgba1 >> 24) & 0xff;
|
||||
if (a1 == 0) continue;
|
||||
if (a1 == 0xff)
|
||||
{
|
||||
row_to[x] = rgba1;
|
||||
continue;
|
||||
}
|
||||
unsigned r1 = rgba1 & 0xff;
|
||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||
|
||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||
unsigned r0 = (rgba0 & 0xff) * a0;
|
||||
unsigned g0 = ((rgba0 >> 8 ) & 0xff) * a0;
|
||||
unsigned b0 = ((rgba0 >> 16) & 0xff) * a0;
|
||||
|
||||
a0 = ((a1 + a0) << 8) - a0*a1;
|
||||
|
||||
r0 = ((((r1 << 8) - r0) * a1 + (r0 << 8)) / a0);
|
||||
g0 = ((((g1 << 8) - g0) * a1 + (g0 << 8)) / a0);
|
||||
b0 = ((((b1 << 8) - b0) * a1 + (b0 << 8)) / a0);
|
||||
a0 = a0 >> 8;
|
||||
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void set_rectangle_alpha2(image_data_rgba8 const& data, unsigned x0, unsigned y0, float opacity)
|
||||
{
|
||||
box2d<int> ext0(0,0,data_.width(),data_.height());
|
||||
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||
|
||||
if (ext0.intersects(ext1))
|
||||
{
|
||||
box2d<int> box = ext0.intersect(ext1);
|
||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||
{
|
||||
unsigned int* row_to = data_.getRow(y);
|
||||
unsigned int const * row_from = data.getRow(y-y0);
|
||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||
{
|
||||
unsigned rgba0 = row_to[x];
|
||||
unsigned rgba1 = row_from[x-x0];
|
||||
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
||||
if (a1 == 0) continue;
|
||||
if (a1 == 0xff)
|
||||
{
|
||||
row_to[x] = rgba1;
|
||||
continue;
|
||||
}
|
||||
unsigned r1 = rgba1 & 0xff;
|
||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||
|
||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||
unsigned r0 = rgba0 & 0xff ;
|
||||
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
||||
unsigned b0 = (rgba0 >> 16) & 0xff;
|
||||
|
||||
unsigned atmp = a1 + a0 - ((a1 * a0 + 255) >> 8);
|
||||
if (atmp)
|
||||
{
|
||||
r0 = byte((r1 * a1 + (r0 * a0) - ((r0 * a0 * a1 + 255) >> 8)) / atmp);
|
||||
g0 = byte((g1 * a1 + (g0 * a0) - ((g0 * a0 * a1 + 255) >> 8)) / atmp);
|
||||
b0 = byte((b1 * a1 + (b0 * a0) - ((b0 * a0 * a1 + 255) >> 8)) / atmp);
|
||||
}
|
||||
a0 = byte(atmp);
|
||||
|
||||
row_to[x] = (a0 << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <typename MergeMethod>
|
||||
inline void merge_rectangle(image_data_rgba8 const& data, unsigned x0, unsigned y0, float opacity)
|
||||
{
|
||||
box2d<int> ext0(0,0,data_.width(),data_.height());
|
||||
box2d<int> ext1(x0,y0,x0 + data.width(),y0 + data.height());
|
||||
|
||||
if (ext0.intersects(ext1))
|
||||
{
|
||||
box2d<int> box = ext0.intersect(ext1);
|
||||
for (int y = box.miny(); y < box.maxy(); ++y)
|
||||
{
|
||||
unsigned int* row_to = data_.getRow(y);
|
||||
unsigned int const * row_from = data.getRow(y-y0);
|
||||
for (int x = box.minx(); x < box.maxx(); ++x)
|
||||
{
|
||||
unsigned rgba0 = row_to[x];
|
||||
unsigned rgba1 = row_from[x-x0];
|
||||
unsigned a1 = int( ((rgba1 >> 24) & 0xff) * opacity );
|
||||
if (a1 == 0) continue;
|
||||
unsigned r1 = rgba1 & 0xff;
|
||||
unsigned g1 = (rgba1 >> 8 ) & 0xff;
|
||||
unsigned b1 = (rgba1 >> 16) & 0xff;
|
||||
|
||||
unsigned a0 = (rgba0 >> 24) & 0xff;
|
||||
unsigned r0 = rgba0 & 0xff ;
|
||||
unsigned g0 = (rgba0 >> 8 ) & 0xff;
|
||||
unsigned b0 = (rgba0 >> 16) & 0xff;
|
||||
|
||||
unsigned a = (a1 * 255 + (255 - a1) * a0 + 127)/255;
|
||||
|
||||
MergeMethod::mergeRGB(r0,g0,b0,r1,g1,b1);
|
||||
|
||||
r0 = (r1*a1 + (((255 - a1) * a0 + 127)/255) * r0 + 127)/a;
|
||||
g0 = (g1*a1 + (((255 - a1) * a0 + 127)/255) * g0 + 127)/a;
|
||||
b0 = (b1*a1 + (((255 - a1) * a0 + 127)/255) * b0 + 127)/a;
|
||||
|
||||
row_to[x] = (a << 24)| (b0 << 16) | (g0 << 8) | (r0) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MAPNIK_GRAPHICS_HPP
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/grid/grid_view.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
|
@ -35,7 +35,6 @@
|
|||
#include <mapnik/util/conversions.hpp>
|
||||
|
||||
// stl
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <cmath>
|
||||
|
@ -49,8 +48,8 @@ template <typename T>
|
|||
class MAPNIK_DECL hit_grid
|
||||
{
|
||||
public:
|
||||
using value_type = T;
|
||||
using data_type = mapnik::image_data<value_type>;
|
||||
using value_type = typename T::type;
|
||||
using data_type = mapnik::image<T>;
|
||||
using lookup_type = std::string;
|
||||
// mapping between pixel id and key
|
||||
using feature_key_type = std::map<value_type, lookup_type>;
|
||||
|
@ -147,12 +146,12 @@ public:
|
|||
return data_;
|
||||
}
|
||||
|
||||
inline T const * raw_data() const
|
||||
inline value_type const * raw_data() const
|
||||
{
|
||||
return data_.getData();
|
||||
}
|
||||
|
||||
inline T* raw_data()
|
||||
inline value_type* raw_data()
|
||||
{
|
||||
return data_.getData();
|
||||
}
|
||||
|
@ -195,7 +194,7 @@ public:
|
|||
return height_;
|
||||
}
|
||||
|
||||
inline void set_rectangle(value_type id,image_data_rgba8 const& data,int x0,int y0)
|
||||
inline void set_rectangle(value_type id,image_rgba8 const& data,int x0,int y0)
|
||||
{
|
||||
box2d<int> ext0(0,0,width_,height_);
|
||||
box2d<int> ext1(x0,y0,x0+data.width(),y0+data.height());
|
||||
|
@ -222,10 +221,9 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
using grid = hit_grid<mapnik::value_integer>;
|
||||
using grid = hit_grid<mapnik::value_integer_pixel>;
|
||||
|
||||
}
|
||||
#endif //MAPNIK_GRID_HPP
|
||||
|
|
|
@ -41,7 +41,7 @@ namespace mapnik {
|
|||
template <typename RendererType, typename RasterizerType>
|
||||
void render_raster_marker(RendererType ren,
|
||||
RasterizerType & ras,
|
||||
image_data_rgba8 & src,
|
||||
image_rgba8 const& src,
|
||||
mapnik::feature_impl const& feature,
|
||||
agg::trans_affine const& marker_tr,
|
||||
double opacity)
|
||||
|
|
|
@ -49,7 +49,7 @@ namespace mapnik {
|
|||
class feature_type_style;
|
||||
class label_collision_detector4;
|
||||
class layer;
|
||||
class marker;
|
||||
struct marker;
|
||||
class proj_transform;
|
||||
struct grid_rasterizer;
|
||||
class request;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef MAPNIK_GRID_VIEW_HPP
|
||||
#define MAPNIK_GRID_VIEW_HPP
|
||||
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/value.hpp>
|
||||
|
@ -196,7 +196,7 @@ private:
|
|||
feature_type const& features_;
|
||||
};
|
||||
|
||||
using grid_view = hit_grid_view<mapnik::image_data<mapnik::value_integer> >;
|
||||
using grid_view = hit_grid_view<mapnik::image<mapnik::value_integer_pixel> >;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -25,10 +25,13 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/pixel_types.hpp>
|
||||
|
||||
// stl
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
|
@ -116,45 +119,70 @@ struct image_dimensions
|
|||
}
|
||||
|
||||
template <typename T, std::size_t max_size = 65535>
|
||||
class image_data
|
||||
class image
|
||||
{
|
||||
public:
|
||||
using pixel_type = T;
|
||||
using pixel = T;
|
||||
using pixel_type = typename T::type;
|
||||
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
||||
|
||||
image_data(int width, int height, bool initialize = true)
|
||||
private:
|
||||
detail::image_dimensions<max_size> dimensions_;
|
||||
detail::buffer buffer_;
|
||||
pixel_type *pData_;
|
||||
double offset_;
|
||||
double scaling_;
|
||||
bool premultiplied_alpha_;
|
||||
bool painted_;
|
||||
public:
|
||||
image(int width, int height, bool initialize = true, bool premultiplied = false, bool painted = false)
|
||||
: dimensions_(width, height),
|
||||
buffer_(dimensions_.width() * dimensions_.height() * pixel_size),
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
|
||||
offset_(0.0),
|
||||
scaling_(1.0),
|
||||
premultiplied_alpha_(premultiplied),
|
||||
painted_(painted)
|
||||
{
|
||||
if (pData_ && initialize) std::fill(pData_, pData_ + dimensions_.width() * dimensions_.height(), 0);
|
||||
}
|
||||
|
||||
image_data(image_data<pixel_type> const& rhs)
|
||||
image(image<T> const& rhs)
|
||||
: dimensions_(rhs.dimensions_),
|
||||
buffer_(rhs.buffer_),
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
|
||||
offset_(rhs.offset_),
|
||||
scaling_(rhs.scaling_),
|
||||
premultiplied_alpha_(rhs.premultiplied_alpha_),
|
||||
painted_(rhs.painted_)
|
||||
{}
|
||||
|
||||
image_data(image_data<pixel_type> && rhs) noexcept
|
||||
image(image<T> && rhs) noexcept
|
||||
: dimensions_(std::move(rhs.dimensions_)),
|
||||
buffer_(std::move(rhs.buffer_)),
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data()))
|
||||
buffer_(std::move(rhs.buffer_)),
|
||||
pData_(reinterpret_cast<pixel_type*>(buffer_.data())),
|
||||
offset_(rhs.offset_),
|
||||
scaling_(rhs.scaling_),
|
||||
premultiplied_alpha_(rhs.premultiplied_alpha_),
|
||||
painted_(rhs.painted_)
|
||||
{
|
||||
rhs.dimensions_ = { 0, 0 };
|
||||
rhs.pData_ = nullptr;
|
||||
}
|
||||
|
||||
image_data<pixel_type>& operator=(image_data<pixel_type> rhs)
|
||||
image<T>& operator=(image<T> rhs)
|
||||
{
|
||||
swap(rhs);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void swap(image_data<pixel_type> & rhs)
|
||||
void swap(image<T> & rhs)
|
||||
{
|
||||
std::swap(dimensions_, rhs.dimensions_);
|
||||
std::swap(buffer_, rhs.buffer_);
|
||||
std::swap(offset_, rhs.offset_);
|
||||
std::swap(scaling_, rhs.scaling_);
|
||||
std::swap(premultiplied_alpha_, rhs.premultiplied_alpha_);
|
||||
std::swap(painted_, rhs.painted_);
|
||||
}
|
||||
|
||||
inline pixel_type& operator() (std::size_t i, std::size_t j)
|
||||
|
@ -241,16 +269,80 @@ public:
|
|||
std::copy(buf, buf + (x1 - x0), pData_ + row * dimensions_.width() + x0);
|
||||
}
|
||||
|
||||
private:
|
||||
detail::image_dimensions<max_size> dimensions_;
|
||||
detail::buffer buffer_;
|
||||
pixel_type *pData_;
|
||||
inline double get_offset() const
|
||||
{
|
||||
return offset_;
|
||||
}
|
||||
|
||||
inline void set_offset(double set)
|
||||
{
|
||||
offset_ = set;
|
||||
}
|
||||
|
||||
inline double get_scaling() const
|
||||
{
|
||||
return scaling_;
|
||||
}
|
||||
|
||||
inline void set_scaling(double set)
|
||||
{
|
||||
if (set != 0.0)
|
||||
{
|
||||
scaling_ = set;
|
||||
return;
|
||||
}
|
||||
std::clog << "Can not set scaling to 0.0, offset not set." << std::endl;
|
||||
}
|
||||
|
||||
inline bool get_premultiplied() const
|
||||
{
|
||||
return premultiplied_alpha_;
|
||||
}
|
||||
|
||||
inline void set_premultiplied(bool set)
|
||||
{
|
||||
premultiplied_alpha_ = set;
|
||||
}
|
||||
|
||||
inline void painted(bool painted)
|
||||
{
|
||||
painted_ = painted;
|
||||
}
|
||||
|
||||
inline bool painted() const
|
||||
{
|
||||
return painted_;
|
||||
}
|
||||
};
|
||||
|
||||
using image_data_rgba8 = image_data<std::uint32_t>;
|
||||
using image_data_gray8 = image_data<std::uint8_t> ;
|
||||
using image_data_gray16 = image_data<std::int16_t>;
|
||||
using image_data_gray32f = image_data<float>;
|
||||
}
|
||||
using image_rgba8 = image<rgba8_t>;
|
||||
using image_gray8 = image<gray8_t>;
|
||||
using image_gray8s = image<gray8s_t>;
|
||||
using image_gray16 = image<gray16_t>;
|
||||
using image_gray16s = image<gray16s_t>;
|
||||
using image_gray32 = image<gray32_t>;
|
||||
using image_gray32s = image<gray32s_t>;
|
||||
using image_gray32f = image<gray32f_t>;
|
||||
using image_gray64 = image<gray64_t>;
|
||||
using image_gray64s = image<gray64s_t>;
|
||||
using image_gray64f = image<gray64f_t>;
|
||||
|
||||
enum image_dtype : std::uint8_t
|
||||
{
|
||||
image_dtype_rgba8 = 0,
|
||||
image_dtype_gray8,
|
||||
image_dtype_gray8s,
|
||||
image_dtype_gray16,
|
||||
image_dtype_gray16s,
|
||||
image_dtype_gray32,
|
||||
image_dtype_gray32s,
|
||||
image_dtype_gray32f,
|
||||
image_dtype_gray64,
|
||||
image_dtype_gray64s,
|
||||
image_dtype_gray64f,
|
||||
image_dtype_null
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_DATA_HPP
|
316
include/mapnik/image_any.hpp
Normal file
316
include/mapnik/image_any.hpp
Normal file
|
@ -0,0 +1,316 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_DATA_ANY_HPP
|
||||
#define MAPNIK_IMAGE_DATA_ANY_HPP
|
||||
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct image_null
|
||||
{
|
||||
using pixel_type = uint8_t;
|
||||
unsigned char const* getBytes() const { return nullptr; }
|
||||
unsigned char* getBytes() { return nullptr;}
|
||||
unsigned getSize() const { return 0; }
|
||||
unsigned getRowSize() const { return 0; }
|
||||
std::size_t width() const { return 0; }
|
||||
std::size_t height() const { return 0; }
|
||||
bool painted() const { return false; }
|
||||
double get_offset() const { return 0.0; }
|
||||
void set_offset(double) {}
|
||||
double get_scaling() const { return 1.0; }
|
||||
void set_scaling(double) {}
|
||||
bool get_premultiplied() const { return false; }
|
||||
void set_premultiplied(bool) {}
|
||||
void set(pixel_type const&) { throw std::runtime_error("Can not set values for null image"); }
|
||||
pixel_type& operator() (std::size_t, std::size_t)
|
||||
{
|
||||
throw std::runtime_error("Can not set or get values for null image");
|
||||
}
|
||||
pixel_type const& operator() (std::size_t, std::size_t) const
|
||||
{
|
||||
throw std::runtime_error("Can not set or get values for null image");
|
||||
}
|
||||
};
|
||||
|
||||
using image_base = util::variant<image_null,
|
||||
image_rgba8,
|
||||
image_gray8,
|
||||
image_gray8s,
|
||||
image_gray16,
|
||||
image_gray16s,
|
||||
image_gray32,
|
||||
image_gray32s,
|
||||
image_gray32f,
|
||||
image_gray64,
|
||||
image_gray64s,
|
||||
image_gray64f>;
|
||||
|
||||
// Forward declaring
|
||||
struct image_any;
|
||||
image_any create_image_any(int width,
|
||||
int height,
|
||||
image_dtype type = image_dtype_rgba8,
|
||||
bool initialize = true,
|
||||
bool premultiplied = false,
|
||||
bool painted = false);
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct get_bytes_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned char* operator()(T & data)
|
||||
{
|
||||
return data.getBytes();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_bytes_visitor_const
|
||||
{
|
||||
template <typename T>
|
||||
unsigned char const* operator()(T const& data) const
|
||||
{
|
||||
return data.getBytes();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_width_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.width();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_height_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.height();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_premultiplied_visitor
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& data) const
|
||||
{
|
||||
return data.get_premultiplied();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_painted_visitor
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& data) const
|
||||
{
|
||||
return data.painted();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_any_size_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned operator()(T const& data) const
|
||||
{
|
||||
return data.getSize();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_any_row_size_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned operator()(T const& data) const
|
||||
{
|
||||
return data.getRowSize();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_offset_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator() (T const& data) const
|
||||
{
|
||||
return data.get_offset();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_scaling_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator() (T const& data) const
|
||||
{
|
||||
return data.get_scaling();
|
||||
}
|
||||
};
|
||||
|
||||
struct set_offset_visitor
|
||||
{
|
||||
set_offset_visitor(double val)
|
||||
: val_(val) {}
|
||||
template <typename T>
|
||||
void operator() (T & data)
|
||||
{
|
||||
data.set_offset(val_);
|
||||
}
|
||||
private:
|
||||
double val_;
|
||||
};
|
||||
|
||||
struct set_scaling_visitor
|
||||
{
|
||||
set_scaling_visitor(double val)
|
||||
: val_(val) {}
|
||||
template <typename T>
|
||||
void operator() (T & data)
|
||||
{
|
||||
data.set_scaling(val_);
|
||||
}
|
||||
private:
|
||||
double val_;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct image_any : image_base
|
||||
{
|
||||
image_any() = default;
|
||||
|
||||
image_any(int width,
|
||||
int height,
|
||||
image_dtype type = image_dtype_rgba8,
|
||||
bool initialize = true,
|
||||
bool premultiplied = false,
|
||||
bool painted = false)
|
||||
: image_base(std::move(create_image_any(width, height, type, initialize, premultiplied, painted))) {}
|
||||
|
||||
template <typename T>
|
||||
image_any(T && data) noexcept
|
||||
: image_base(std::move(data)) {}
|
||||
|
||||
unsigned char const* getBytes() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_bytes_visitor_const(),*this);
|
||||
}
|
||||
|
||||
unsigned char* getBytes()
|
||||
{
|
||||
return util::apply_visitor(detail::get_bytes_visitor(),*this);
|
||||
}
|
||||
|
||||
std::size_t width() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_width_visitor(),*this);
|
||||
}
|
||||
|
||||
std::size_t height() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_height_visitor(),*this);
|
||||
}
|
||||
|
||||
bool get_premultiplied() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_premultiplied_visitor(),*this);
|
||||
}
|
||||
|
||||
bool painted() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_painted_visitor(),*this);
|
||||
}
|
||||
|
||||
unsigned getSize() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_any_size_visitor(),*this);
|
||||
}
|
||||
|
||||
unsigned getRowSize() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_any_row_size_visitor(),*this);
|
||||
}
|
||||
|
||||
double get_offset() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_offset_visitor(),*this);
|
||||
}
|
||||
|
||||
double get_scaling() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_scaling_visitor(),*this);
|
||||
}
|
||||
|
||||
void set_offset(double val)
|
||||
{
|
||||
util::apply_visitor(detail::set_offset_visitor(val),*this);
|
||||
}
|
||||
|
||||
void set_scaling(double val)
|
||||
{
|
||||
util::apply_visitor(detail::set_scaling_visitor(val),*this);
|
||||
}
|
||||
};
|
||||
|
||||
inline image_any create_image_any(int width,
|
||||
int height,
|
||||
image_dtype type,
|
||||
bool initialize,
|
||||
bool premultiplied,
|
||||
bool painted)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case image_dtype_gray8:
|
||||
return image_any(std::move(image_gray8(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray8s:
|
||||
return image_any(std::move(image_gray8s(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray16:
|
||||
return image_any(std::move(image_gray16(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray16s:
|
||||
return image_any(std::move(image_gray16s(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray32:
|
||||
return image_any(std::move(image_gray32(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray32s:
|
||||
return image_any(std::move(image_gray32s(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray32f:
|
||||
return image_any(std::move(image_gray32f(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray64:
|
||||
return image_any(std::move(image_gray64(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray64s:
|
||||
return image_any(std::move(image_gray64s(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_gray64f:
|
||||
return image_any(std::move(image_gray64f(width, height, initialize, premultiplied, painted)));
|
||||
case image_dtype_null:
|
||||
return image_any(std::move(image_null()));
|
||||
case image_dtype_rgba8:
|
||||
default:
|
||||
return image_any(std::move(image_rgba8(width, height, initialize, premultiplied, painted)));
|
||||
}
|
||||
}
|
||||
|
||||
} // end mapnik ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_DATA_ANY_HPP
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_IMAGE_COMPOSITING_HPP
|
||||
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
|
@ -87,8 +87,7 @@ MAPNIK_DECL void composite(T & dst, T const& src,
|
|||
composite_mode_e mode,
|
||||
float opacity=1,
|
||||
int dx=0,
|
||||
int dy=0,
|
||||
bool premultiply_src=false);
|
||||
int dy=0);
|
||||
|
||||
}
|
||||
#endif // MAPNIK_IMAGE_COMPOSITING_HPP
|
||||
|
|
72
include/mapnik/image_copy.hpp
Normal file
72
include/mapnik/image_copy.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_COPY_HPP
|
||||
#define MAPNIK_IMAGE_COPY_HPP
|
||||
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_any const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_rgba8 const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray8 const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray8s const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray16 const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray16s const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray32 const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray32s const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray32f const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray64 const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray64s const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T image_copy(image_gray64f const&, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
MAPNIK_DECL image_any image_copy(image_any const&, image_dtype type, double offset = 0.0, double scaling = 1.0);
|
||||
|
||||
} // end mapnik ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_COPY_HPP
|
|
@ -1,112 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_DATA_ANY_HPP
|
||||
#define MAPNIK_IMAGE_DATA_ANY_HPP
|
||||
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct image_data_null
|
||||
{
|
||||
unsigned char const* getBytes() const { return nullptr; }
|
||||
unsigned char* getBytes() { return nullptr;}
|
||||
std::size_t width() const { return 0; }
|
||||
std::size_t height() const { return 0; }
|
||||
};
|
||||
|
||||
using image_data_base = util::variant<image_data_null, image_data_rgba8, image_data_gray8, image_data_gray16, image_data_gray32f>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct get_bytes_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned char* operator()(T & data)
|
||||
{
|
||||
return data.getBytes();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_bytes_visitor_const
|
||||
{
|
||||
template <typename T>
|
||||
unsigned char const* operator()(T const& data) const
|
||||
{
|
||||
return data.getBytes();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_width_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.width();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_height_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.height();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
struct image_data_any : image_data_base
|
||||
{
|
||||
image_data_any() = default;
|
||||
|
||||
template <typename T>
|
||||
image_data_any(T && data) noexcept
|
||||
: image_data_base(std::move(data)) {}
|
||||
|
||||
unsigned char const* getBytes() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_bytes_visitor_const(),*this);
|
||||
}
|
||||
|
||||
unsigned char* getBytes()
|
||||
{
|
||||
return util::apply_visitor(detail::get_bytes_visitor(),*this);
|
||||
}
|
||||
|
||||
std::size_t width() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_width_visitor(),*this);
|
||||
}
|
||||
|
||||
std::size_t height() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_height_visitor(),*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_IMAGE_DATA_ANY_HPP
|
|
@ -139,7 +139,7 @@ boost::gil::rgba8_view_t rgba8_view(Image & img)
|
|||
using boost::gil::interleaved_view;
|
||||
using boost::gil::rgba8_pixel_t;
|
||||
return interleaved_view(img.width(), img.height(),
|
||||
reinterpret_cast<rgba8_pixel_t*>(img.raw_data()),
|
||||
reinterpret_cast<rgba8_pixel_t*>(img.getBytes()),
|
||||
img.width() * sizeof(rgba8_pixel_t));
|
||||
}
|
||||
|
||||
|
@ -391,17 +391,17 @@ template <typename Src, typename Filter>
|
|||
void apply_filter(Src & src, Filter const& filter)
|
||||
{
|
||||
{
|
||||
src.demultiply();
|
||||
demultiply_alpha(src);
|
||||
double_buffer<Src> tb(src);
|
||||
apply_convolution_3x3(tb.src_view, tb.dst_view, filter);
|
||||
} // ensure ~double_buffer() is called before premultiplying
|
||||
src.premultiply();
|
||||
premultiply_alpha(src);
|
||||
}
|
||||
|
||||
template <typename Src>
|
||||
void apply_filter(Src & src, agg_stack_blur const& op)
|
||||
{
|
||||
agg::rendering_buffer buf(src.raw_data(),src.width(),src.height(), src.width() * 4);
|
||||
agg::rendering_buffer buf(src.getBytes(),src.width(),src.height(), src.getRowSize());
|
||||
agg::pixfmt_rgba32_pre pixf(buf);
|
||||
agg::stack_blur_rgba32(pixf,op.rx,op.ry);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_IMAGE_READER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data_any.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
#include <mapnik/factory.hpp>
|
||||
|
@ -59,10 +59,9 @@ struct MAPNIK_DECL image_reader : private util::noncopyable
|
|||
virtual unsigned width() const = 0;
|
||||
virtual unsigned height() const = 0;
|
||||
virtual bool has_alpha() const = 0;
|
||||
virtual bool premultiplied_alpha() const = 0;
|
||||
virtual boost::optional<box2d<double> > bounding_box() const = 0;
|
||||
virtual void read(unsigned x,unsigned y,image_data_rgba8& image) = 0;
|
||||
virtual image_data_any read(unsigned x, unsigned y, unsigned width, unsigned height) = 0;
|
||||
virtual void read(unsigned x,unsigned y,image_rgba8& image) = 0;
|
||||
virtual image_any read(unsigned x, unsigned y, unsigned width, unsigned height) = 0;
|
||||
virtual ~image_reader() {}
|
||||
};
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
|
||||
// stl
|
||||
#include <iosfwd>
|
||||
|
|
|
@ -38,7 +38,7 @@ template <typename T>
|
|||
struct agg_scaling_traits {};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_data_rgba8>
|
||||
struct agg_scaling_traits<image_rgba8>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_rgba32_pre;
|
||||
using color_type = agg::rgba8;
|
||||
|
@ -50,7 +50,7 @@ struct agg_scaling_traits<image_data_rgba8>
|
|||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_data_gray8>
|
||||
struct agg_scaling_traits<image_gray8>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray8_pre;
|
||||
using color_type = agg::gray8;
|
||||
|
@ -61,7 +61,18 @@ struct agg_scaling_traits<image_data_gray8>
|
|||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_data_gray16>
|
||||
struct agg_scaling_traits<image_gray8s>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray8_pre;
|
||||
using color_type = agg::gray8;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray16>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray16_pre;
|
||||
using color_type = agg::gray16;
|
||||
|
@ -72,7 +83,73 @@ struct agg_scaling_traits<image_data_gray16>
|
|||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_data_gray32f>
|
||||
struct agg_scaling_traits<image_gray16s>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray16_pre;
|
||||
using color_type = agg::gray16;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray32>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray32s>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray32f>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray64>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray64s>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
using interpolator_type = agg::span_interpolator_linear<>;
|
||||
using img_src_type = agg::image_accessor_clone<pixfmt_pre>;
|
||||
using span_image_filter = agg::span_image_filter_gray_nn<img_src_type,interpolator_type>;
|
||||
using span_image_resample_affine = agg::span_image_resample_gray_affine<img_src_type>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct agg_scaling_traits<image_gray64f>
|
||||
{
|
||||
using pixfmt_pre = agg::pixfmt_gray32_pre;
|
||||
using color_type = agg::gray32;
|
||||
|
|
|
@ -25,8 +25,11 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <mapnik/image_view_any.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
// boost
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -37,13 +40,11 @@
|
|||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <exception>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
// fwd declares
|
||||
class Map;
|
||||
class rgba_palette;
|
||||
|
||||
class ImageWriterException : public std::exception
|
||||
|
@ -62,18 +63,6 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
|
||||
std::string const& filename,
|
||||
double scale_factor=1.0,
|
||||
double scale_denominator=0.0);
|
||||
MAPNIK_DECL void save_to_cairo_file(mapnik::Map const& map,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
double scale_factor=1.0,
|
||||
double scale_denominator=0.0);
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void save_to_file(T const& image,
|
||||
std::string const& filename,
|
||||
|
@ -121,17 +110,228 @@ MAPNIK_DECL void save_to_stream
|
|||
std::string const& type
|
||||
);
|
||||
|
||||
template <typename T>
|
||||
void save_as_png(T const& image,
|
||||
std::string const& filename,
|
||||
rgba_palette const& palette);
|
||||
// PREMULTIPLY ALPHA
|
||||
MAPNIK_DECL bool premultiply_alpha(image_any & image);
|
||||
|
||||
#if defined(HAVE_JPEG)
|
||||
template <typename T>
|
||||
void save_as_jpeg(std::string const& filename,
|
||||
int quality,
|
||||
T const& image);
|
||||
#endif
|
||||
MAPNIK_DECL bool premultiply_alpha(T & image);
|
||||
|
||||
// DEMULTIPLY ALPHA
|
||||
MAPNIK_DECL bool demultiply_alpha(image_any & image);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL bool demultiply_alpha(T & image);
|
||||
|
||||
// SET PREMULTIPLIED ALPHA
|
||||
MAPNIK_DECL void set_premultiplied_alpha(image_any & image, bool status);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_premultiplied_alpha(T & image, bool status);
|
||||
|
||||
// IS SOLID
|
||||
MAPNIK_DECL bool is_solid (image_any const& image);
|
||||
MAPNIK_DECL bool is_solid (image_view_any const& image);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL bool is_solid (T const& image);
|
||||
|
||||
// SET ALPHA
|
||||
MAPNIK_DECL void set_alpha (image_any & image, float opacity);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_alpha (T & image, float opacity);
|
||||
|
||||
// SET GRAYSCALE TO ALPHA
|
||||
MAPNIK_DECL void set_grayscale_to_alpha (image_any & image);
|
||||
MAPNIK_DECL void set_grayscale_to_alpha (image_any & image, color const& c);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_grayscale_to_alpha (T & image);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_grayscale_to_alpha (T & image, color const& c);
|
||||
|
||||
// SET COLOR TO ALPHA
|
||||
MAPNIK_DECL void set_color_to_alpha (image_any & image, color const& c);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_color_to_alpha (T & image, color const& c);
|
||||
|
||||
// FILL
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_any & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_rgba8 & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray8 & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray8s & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray16 & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray16s & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray32 & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray32s & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray32f & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray64 & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray64s & data, T const&);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void fill (image_gray64f & data, T const&);
|
||||
|
||||
// SET RECTANGLE
|
||||
MAPNIK_DECL void set_rectangle (image_any & dst, image_any const& src, int x = 0, int y = 0);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_rectangle (T & dst, T const& src, int x = 0, int y = 0);
|
||||
|
||||
// CHECK BOUNDS
|
||||
template <typename T>
|
||||
inline bool check_bounds (T const& data, std::size_t x, std::size_t y)
|
||||
{
|
||||
return (x < static_cast<int>(data.width()) && y < static_cast<int>(data.height()));
|
||||
}
|
||||
|
||||
// COMPOSITE_PIXEL
|
||||
MAPNIK_DECL void composite_pixel(image_any & data, unsigned op, int x, int y, unsigned c, unsigned cover, double opacity );
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void composite_pixel(T & data, unsigned op, int x, int y, unsigned c, unsigned cover, double opacity );
|
||||
|
||||
// SET PIXEL
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_any & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_rgba8 & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray8 & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray8s & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray16 & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray16s & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray32 & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray32s & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray32f & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray64 & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray64s & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL void set_pixel(image_gray64f & data, std::size_t x, std::size_t y, T const& val);
|
||||
|
||||
// GET PIXEL
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_any const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_any const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_rgba8 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray8 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray8s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray16 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray16s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray32 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray32s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray32f const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray64 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray64s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_gray64f const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_rgba8 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray8 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray8s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray16 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray16s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray32 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray32s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray32f const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray64 const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray64s const& data, std::size_t x, std::size_t y);
|
||||
|
||||
template <typename T>
|
||||
MAPNIK_DECL T get_pixel(image_view_gray64f const& data, std::size_t x, std::size_t y);
|
||||
|
||||
// VIEW TO STRING
|
||||
MAPNIK_DECL void view_to_string (image_view_any const& view, std::ostringstream & ss);
|
||||
|
||||
// CREATE VIEW
|
||||
MAPNIK_DECL image_view_any create_view (image_any const& data, unsigned x, unsigned y, unsigned w, unsigned h);
|
||||
|
||||
// COMPARE
|
||||
template <typename T>
|
||||
MAPNIK_DECL unsigned compare(T const& im1, T const& im2, double threshold = 0, bool alpha = true);
|
||||
|
||||
inline bool is_png(std::string const& filename)
|
||||
{
|
||||
|
@ -209,82 +409,6 @@ void add_border(T & image)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&);
|
||||
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
|
||||
extern template MAPNIK_DECL void save_to_file<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_data_rgba8>(image_data_rgba8 const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&);
|
||||
|
||||
extern template MAPNIK_DECL std::string save_to_string<image_view<image_data_rgba8> > (image_view<image_data_rgba8> const&,
|
||||
std::string const&,
|
||||
rgba_palette const&);
|
||||
#ifdef _MSC_VER
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_data_rgba8>(
|
||||
image_data_rgba8 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette
|
||||
);
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_data_rgba8>(
|
||||
image_data_rgba8 const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type
|
||||
);
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_view<image_data_rgba8> > (
|
||||
image_view<image_data_rgba8> const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type,
|
||||
rgba_palette const& palette
|
||||
);
|
||||
|
||||
template MAPNIK_DECL void save_to_stream<image_view<image_data_rgba8> > (
|
||||
image_view<image_data_rgba8> const& image,
|
||||
std::ostream & stream,
|
||||
std::string const& type
|
||||
);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_HPP
|
||||
|
|
44
include/mapnik/image_util_jpeg.hpp
Normal file
44
include/mapnik/image_util_jpeg.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_UTIL_JPEG_HPP
|
||||
#define MAPNIK_IMAGE_UTIL_JPEG_HPP
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct jpeg_saver
|
||||
{
|
||||
jpeg_saver(std::ostream &, std::string const&);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream & stream_;
|
||||
std::string const& t_;
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_JPEG_HPP
|
55
include/mapnik/image_util_png.hpp
Normal file
55
include/mapnik/image_util_png.hpp
Normal file
|
@ -0,0 +1,55 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_UTIL_PNG_HPP
|
||||
#define MAPNIK_IMAGE_UTIL_PNG_HPP
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct png_saver_pal
|
||||
{
|
||||
png_saver_pal(std::ostream &, std::string const&, rgba_palette const&);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream & stream_;
|
||||
std::string const& t_;
|
||||
rgba_palette const& pal_;
|
||||
};
|
||||
|
||||
struct png_saver
|
||||
{
|
||||
png_saver(std::ostream &, std::string const&);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream & stream_;
|
||||
std::string const& t_;
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_PNG_HPP
|
44
include/mapnik/image_util_tiff.hpp
Normal file
44
include/mapnik/image_util_tiff.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_UTIL_TIFF_HPP
|
||||
#define MAPNIK_IMAGE_UTIL_TIFF_HPP
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct tiff_saver
|
||||
{
|
||||
tiff_saver(std::ostream &, std::string const&);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream & stream_;
|
||||
std::string const& t_;
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_TIFF_HPP
|
44
include/mapnik/image_util_webp.hpp
Normal file
44
include/mapnik/image_util_webp.hpp
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_UTIL_WEBP_HPP
|
||||
#define MAPNIK_IMAGE_UTIL_WEBP_HPP
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
struct webp_saver
|
||||
{
|
||||
webp_saver(std::ostream &, std::string const&);
|
||||
template <typename T>
|
||||
void operator() (T const&) const;
|
||||
private:
|
||||
std::ostream & stream_;
|
||||
std::string const& t_;
|
||||
};
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_UTIL_WEBP_HPP
|
|
@ -23,12 +23,15 @@
|
|||
#ifndef MAPNIK_IMAGE_VIEW_HPP
|
||||
#define MAPNIK_IMAGE_VIEW_HPP
|
||||
|
||||
#include <mapnik/image.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename T>
|
||||
class image_view
|
||||
{
|
||||
public:
|
||||
using pixel = typename T::pixel;
|
||||
using pixel_type = typename T::pixel_type;
|
||||
static constexpr std::size_t pixel_size = sizeof(pixel_type);
|
||||
|
||||
|
@ -84,6 +87,10 @@ public:
|
|||
{
|
||||
return height_;
|
||||
}
|
||||
inline const pixel_type& operator() (std::size_t i, std::size_t j) const
|
||||
{
|
||||
return data_(i,j);
|
||||
}
|
||||
|
||||
inline unsigned getSize() const
|
||||
{
|
||||
|
@ -110,6 +117,21 @@ public:
|
|||
return data_;
|
||||
}
|
||||
|
||||
inline bool get_premultiplied() const
|
||||
{
|
||||
return data_.get_premultiplied();
|
||||
}
|
||||
|
||||
inline double get_offset() const
|
||||
{
|
||||
return data_.get_offset();
|
||||
}
|
||||
|
||||
inline double get_scaling() const
|
||||
{
|
||||
return data_.get_scaling();
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned x_;
|
||||
unsigned y_;
|
||||
|
@ -117,6 +139,19 @@ private:
|
|||
unsigned height_;
|
||||
T const& data_;
|
||||
};
|
||||
}
|
||||
|
||||
using image_view_rgba8 = image_view<image_rgba8>;
|
||||
using image_view_gray8 = image_view<image_gray8>;
|
||||
using image_view_gray8s = image_view<image_gray8s>;
|
||||
using image_view_gray16 = image_view<image_gray16>;
|
||||
using image_view_gray16s = image_view<image_gray16s>;
|
||||
using image_view_gray32 = image_view<image_gray32>;
|
||||
using image_view_gray32s = image_view<image_gray32s>;
|
||||
using image_view_gray32f = image_view<image_gray32f>;
|
||||
using image_view_gray64 = image_view<image_gray64>;
|
||||
using image_view_gray64s = image_view<image_gray64s>;
|
||||
using image_view_gray64f = image_view<image_gray64f>;
|
||||
|
||||
} // end ns
|
||||
|
||||
#endif // MAPNIK_IMAGE_VIEW_HPP
|
||||
|
|
155
include/mapnik/image_view_any.hpp
Normal file
155
include/mapnik/image_view_any.hpp
Normal file
|
@ -0,0 +1,155 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_IMAGE_VIEW_ANY_HPP
|
||||
#define MAPNIK_IMAGE_VIEW_ANY_HPP
|
||||
|
||||
#include <mapnik/image_view.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
using image_view_base = util::variant<image_view_rgba8,
|
||||
image_view_gray8,
|
||||
image_view_gray8s,
|
||||
image_view_gray16,
|
||||
image_view_gray16s,
|
||||
image_view_gray32,
|
||||
image_view_gray32s,
|
||||
image_view_gray32f,
|
||||
image_view_gray64,
|
||||
image_view_gray64s,
|
||||
image_view_gray64f>;
|
||||
|
||||
namespace detail {
|
||||
|
||||
struct get_view_width_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.width();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_height_visitor
|
||||
{
|
||||
template <typename T>
|
||||
std::size_t operator()(T const& data) const
|
||||
{
|
||||
return data.height();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_size_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned operator()(T const& data) const
|
||||
{
|
||||
return data.getSize();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_row_size_visitor
|
||||
{
|
||||
template <typename T>
|
||||
unsigned operator()(T const& data) const
|
||||
{
|
||||
return data.getRowSize();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_premultiplied_visitor
|
||||
{
|
||||
template <typename T>
|
||||
bool operator()(T const& data) const
|
||||
{
|
||||
return data.get_premultiplied();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_offset_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator()(T const& data) const
|
||||
{
|
||||
return data.get_offset();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_view_scaling_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator()(T const& data) const
|
||||
{
|
||||
return data.get_scaling();
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
struct image_view_any : image_view_base
|
||||
{
|
||||
image_view_any() = default;
|
||||
|
||||
template <typename T>
|
||||
image_view_any(T && data) noexcept
|
||||
: image_view_base(std::move(data)) {}
|
||||
|
||||
std::size_t width() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_width_visitor(),*this);
|
||||
}
|
||||
|
||||
std::size_t height() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_height_visitor(),*this);
|
||||
}
|
||||
|
||||
unsigned getSize() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_size_visitor(),*this);
|
||||
}
|
||||
|
||||
unsigned getRowSize() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_row_size_visitor(),*this);
|
||||
}
|
||||
|
||||
bool get_premultiplied() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_premultiplied_visitor(),*this);
|
||||
}
|
||||
|
||||
double get_offset() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_offset_visitor(),*this);
|
||||
}
|
||||
|
||||
double get_scaling() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_view_scaling_visitor(),*this);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MAPNIK_IMAGE_VIEW_ANY_HPP
|
|
@ -24,11 +24,13 @@
|
|||
#define MAPNIK_MARKER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/svg/svg_storage.hpp>
|
||||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_array.h"
|
||||
|
@ -45,97 +47,169 @@ namespace mapnik
|
|||
using attr_storage = agg::pod_bvector<mapnik::svg::path_attributes>;
|
||||
using svg_storage_type = mapnik::svg::svg_storage<mapnik::svg::svg_path_storage,attr_storage>;
|
||||
using svg_path_ptr = std::shared_ptr<svg_storage_type>;
|
||||
using image_ptr = std::shared_ptr<image_data_rgba8>;
|
||||
/**
|
||||
* A class to hold either vector or bitmap marker data. This allows these to be treated equally
|
||||
* in the image caches and most of the render paths.
|
||||
*/
|
||||
class marker: private util::noncopyable
|
||||
using image_ptr = std::shared_ptr<image_any>;
|
||||
|
||||
struct marker_rgba8
|
||||
{
|
||||
public:
|
||||
marker()
|
||||
marker_rgba8()
|
||||
: bitmap_data_(4,4,true,true)
|
||||
{
|
||||
// create default OGC 4x4 black pixel
|
||||
bitmap_data_ = boost::optional<mapnik::image_ptr>(std::make_shared<image_data_rgba8>(4,4));
|
||||
(*bitmap_data_)->set(0xff000000);
|
||||
bitmap_data_.set(0xff000000);
|
||||
}
|
||||
|
||||
marker(boost::optional<mapnik::image_ptr> const& data)
|
||||
marker_rgba8(image_rgba8 const & data)
|
||||
: bitmap_data_(data) {}
|
||||
|
||||
marker_rgba8(image_rgba8 && data)
|
||||
: bitmap_data_(std::move(data)) {}
|
||||
|
||||
marker(boost::optional<mapnik::svg_path_ptr> const& data)
|
||||
: vector_data_(data) {}
|
||||
marker_rgba8(marker_rgba8 const& rhs)
|
||||
: bitmap_data_(rhs.bitmap_data_) {}
|
||||
|
||||
marker(marker const& rhs)
|
||||
: bitmap_data_(rhs.bitmap_data_),
|
||||
vector_data_(rhs.vector_data_) {}
|
||||
marker_rgba8(marker_rgba8 && rhs) noexcept
|
||||
: bitmap_data_(std::move(rhs.bitmap_data_)) {}
|
||||
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
if (is_vector())
|
||||
{
|
||||
return (*vector_data_)->bounding_box();
|
||||
}
|
||||
if (is_bitmap())
|
||||
{
|
||||
double width = (*bitmap_data_)->width();
|
||||
double height = (*bitmap_data_)->height();
|
||||
return box2d<double>(0, 0, width, height);
|
||||
}
|
||||
return box2d<double>();
|
||||
double width = bitmap_data_.width();
|
||||
double height = bitmap_data_.height();
|
||||
return box2d<double>(0, 0, width, height);
|
||||
}
|
||||
|
||||
inline double width() const
|
||||
inline std::size_t width() const
|
||||
{
|
||||
if (is_bitmap())
|
||||
{
|
||||
return (*bitmap_data_)->width();
|
||||
}
|
||||
else if (is_vector())
|
||||
{
|
||||
return (*vector_data_)->bounding_box().width();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
inline double height() const
|
||||
{
|
||||
if (is_bitmap())
|
||||
{
|
||||
return (*bitmap_data_)->height();
|
||||
}
|
||||
else if (is_vector())
|
||||
{
|
||||
return (*vector_data_)->bounding_box().height();
|
||||
}
|
||||
return 0;
|
||||
return bitmap_data_.width();
|
||||
}
|
||||
|
||||
inline bool is_bitmap() const
|
||||
inline std::size_t height() const
|
||||
{
|
||||
return !!bitmap_data_;
|
||||
return bitmap_data_.height();
|
||||
}
|
||||
|
||||
inline bool is_vector() const
|
||||
{
|
||||
return !!vector_data_;
|
||||
}
|
||||
|
||||
boost::optional<mapnik::image_ptr> get_bitmap_data() const
|
||||
image_rgba8 const& get_data() const
|
||||
{
|
||||
return bitmap_data_;
|
||||
}
|
||||
|
||||
boost::optional<mapnik::svg_path_ptr> get_vector_data() const
|
||||
private:
|
||||
image_rgba8 bitmap_data_;
|
||||
};
|
||||
|
||||
struct marker_svg
|
||||
{
|
||||
public:
|
||||
marker_svg() { }
|
||||
|
||||
marker_svg(mapnik::svg_path_ptr data)
|
||||
: vector_data_(data) {}
|
||||
|
||||
marker_svg(marker_svg const& rhs)
|
||||
: vector_data_(rhs.vector_data_) {}
|
||||
|
||||
marker_svg(marker_svg && rhs) noexcept
|
||||
: vector_data_(rhs.vector_data_) {}
|
||||
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
return vector_data_->bounding_box();
|
||||
}
|
||||
|
||||
inline double width() const
|
||||
{
|
||||
return vector_data_->bounding_box().width();
|
||||
}
|
||||
inline double height() const
|
||||
{
|
||||
return vector_data_->bounding_box().height();
|
||||
}
|
||||
|
||||
mapnik::svg_path_ptr get_data() const
|
||||
{
|
||||
return vector_data_;
|
||||
}
|
||||
|
||||
private:
|
||||
boost::optional<mapnik::image_ptr> bitmap_data_;
|
||||
boost::optional<mapnik::svg_path_ptr> vector_data_;
|
||||
mapnik::svg_path_ptr vector_data_;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
struct marker_null
|
||||
{
|
||||
public:
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
return box2d<double>();
|
||||
}
|
||||
inline double width() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
inline double height() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
using marker_base = util::variant<marker_svg,
|
||||
marker_rgba8,
|
||||
marker_null>;
|
||||
namespace detail {
|
||||
|
||||
struct get_marker_bbox_visitor
|
||||
{
|
||||
template <typename T>
|
||||
box2d<double> operator()(T & data) const
|
||||
{
|
||||
return data.bounding_box();
|
||||
}
|
||||
};
|
||||
|
||||
struct get_marker_width_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator()(T const& data) const
|
||||
{
|
||||
return static_cast<double>(data.width());
|
||||
}
|
||||
};
|
||||
|
||||
struct get_marker_height_visitor
|
||||
{
|
||||
template <typename T>
|
||||
double operator()(T const& data) const
|
||||
{
|
||||
return static_cast<double>(data.height());
|
||||
}
|
||||
};
|
||||
|
||||
} // end detail ns
|
||||
|
||||
struct marker : marker_base
|
||||
{
|
||||
marker() = default;
|
||||
|
||||
template <typename T>
|
||||
marker(T && data) noexcept
|
||||
: marker_base(std::move(data)) {}
|
||||
|
||||
double width() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_marker_width_visitor(),*this);
|
||||
}
|
||||
|
||||
double height() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_marker_height_visitor(),*this);
|
||||
}
|
||||
|
||||
box2d<double> bounding_box() const
|
||||
{
|
||||
return util::apply_visitor(detail::get_marker_bbox_visitor(),*this);
|
||||
}
|
||||
};
|
||||
|
||||
} // end mapnik ns
|
||||
|
||||
#endif // MAPNIK_MARKER_HPP
|
||||
|
|
|
@ -36,10 +36,7 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
class marker;
|
||||
|
||||
using marker_ptr = std::shared_ptr<marker>;
|
||||
|
||||
struct marker;
|
||||
|
||||
class MAPNIK_DECL marker_cache :
|
||||
public singleton <marker_cache, CreateUsingNew>,
|
||||
|
@ -49,8 +46,8 @@ class MAPNIK_DECL marker_cache :
|
|||
private:
|
||||
marker_cache();
|
||||
~marker_cache();
|
||||
bool insert_marker(std::string const& key, marker_ptr path);
|
||||
boost::unordered_map<std::string,marker_ptr> marker_cache_;
|
||||
bool insert_marker(std::string const& key, marker && path);
|
||||
boost::unordered_map<std::string, mapnik::marker> marker_cache_;
|
||||
bool insert_svg(std::string const& name, std::string const& svg_string);
|
||||
boost::unordered_map<std::string,std::string> svg_cache_;
|
||||
public:
|
||||
|
@ -59,7 +56,7 @@ public:
|
|||
inline bool is_uri(std::string const& path) { return is_svg_uri(path) || is_image_uri(path); }
|
||||
bool is_svg_uri(std::string const& path);
|
||||
bool is_image_uri(std::string const& path);
|
||||
boost::optional<marker_ptr> find(std::string const& key, bool update_cache = false);
|
||||
marker const& find(std::string const& key, bool update_cache = false);
|
||||
void clear();
|
||||
};
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ protected:
|
|||
template <typename Detector>
|
||||
struct raster_markers_dispatch : util::noncopyable
|
||||
{
|
||||
raster_markers_dispatch(image_data_rgba8 & src,
|
||||
raster_markers_dispatch(image_rgba8 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
symbolizer_base const& sym,
|
||||
Detector & detector,
|
||||
|
@ -163,7 +163,7 @@ struct raster_markers_dispatch : util::noncopyable
|
|||
virtual void render_marker(agg::trans_affine const& marker_tr, double opacity) = 0;
|
||||
|
||||
protected:
|
||||
image_data_rgba8 & src_;
|
||||
image_rgba8 const& src_;
|
||||
agg::trans_affine const& marker_trans_;
|
||||
symbolizer_base const& sym_;
|
||||
Detector & detector_;
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_view.hpp>
|
||||
|
||||
/* miniz.c porting issues:
|
||||
|
@ -83,12 +83,12 @@ private:
|
|||
static const unsigned char IEND_tpl[];
|
||||
};
|
||||
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_data_gray8>(image_data_gray8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_view<image_data_gray8> >(image_view<image_data_gray8> const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_data_rgba8>(image_data_rgba8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_view<image_data_rgba8> >(image_view<image_data_rgba8> const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDATStripAlpha<image_data_rgba8>(image_data_rgba8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDATStripAlpha<image_view<image_data_rgba8> >(image_view<image_data_rgba8> const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_gray8>(image_gray8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_view_gray8>(image_view_gray8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_rgba8>(image_rgba8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDAT<image_view_rgba8>(image_view_rgba8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDATStripAlpha<image_rgba8>(image_rgba8 const& image);
|
||||
extern template MAPNIK_DECL void PNGWriter::writeIDATStripAlpha<image_view_rgba8>(image_view_rgba8 const& image);
|
||||
|
||||
}}
|
||||
|
||||
|
|
40
include/mapnik/pixel_types.hpp
Normal file
40
include/mapnik/pixel_types.hpp
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_PIXEL_TYPES_HPP
|
||||
#define MAPNIK_PIXEL_TYPES_HPP
|
||||
|
||||
#include <mapnik/global.hpp>
|
||||
|
||||
struct rgba8_t { using type = std::uint32_t; };
|
||||
struct gray8_t { using type = std::uint8_t; };
|
||||
struct gray8s_t { using type = std::int8_t; };
|
||||
struct gray16_t { using type = std::uint16_t; };
|
||||
struct gray16s_t { using type = std::int16_t; };
|
||||
struct gray32_t { using type = std::uint32_t; };
|
||||
struct gray32s_t { using type = std::int32_t; };
|
||||
struct gray32f_t { using type = float; };
|
||||
struct gray64_t { using type = std::uint64_t; };
|
||||
struct gray64s_t { using type = std::int64_t; };
|
||||
struct gray64f_t { using type = double; };
|
||||
|
||||
#endif // MAPNIK_PIXEL_TYPES_HPP
|
|
@ -28,7 +28,7 @@
|
|||
#include <mapnik/octree.hpp>
|
||||
#include <mapnik/hextree.hpp>
|
||||
#include <mapnik/miniz_png.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
|
||||
// zlib
|
||||
#include <zlib.h> // for Z_DEFAULT_COMPRESSION
|
||||
|
@ -149,7 +149,7 @@ void save_as_png(T1 & file,
|
|||
|
||||
template <typename T>
|
||||
void reduce_8(T const& in,
|
||||
image_data_gray8 & out,
|
||||
image_gray8 & out,
|
||||
octree<rgb> trees[],
|
||||
unsigned limits[],
|
||||
unsigned levels,
|
||||
|
@ -166,8 +166,8 @@ void reduce_8(T const& in,
|
|||
}
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::image_data_rgba8::pixel_type const * row = in.getRow(y);
|
||||
mapnik::image_data_gray8::pixel_type * row_out = out.getRow(y);
|
||||
mapnik::image_rgba8::pixel_type const * row = in.getRow(y);
|
||||
mapnik::image_gray8::pixel_type * row_out = out.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
|
@ -200,7 +200,7 @@ void reduce_8(T const& in,
|
|||
|
||||
template <typename T>
|
||||
void reduce_4(T const& in,
|
||||
image_data_gray8 & out,
|
||||
image_gray8 & out,
|
||||
octree<rgb> trees[],
|
||||
unsigned limits[],
|
||||
unsigned levels,
|
||||
|
@ -217,8 +217,8 @@ void reduce_4(T const& in,
|
|||
}
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::image_data_rgba8::pixel_type const * row = in.getRow(y);
|
||||
mapnik::image_data_gray8::pixel_type * row_out = out.getRow(y);
|
||||
mapnik::image_rgba8::pixel_type const * row = in.getRow(y);
|
||||
mapnik::image_gray8::pixel_type * row_out = out.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
unsigned val = row[x];
|
||||
|
@ -256,7 +256,7 @@ void reduce_4(T const& in,
|
|||
// 1-bit but only one color.
|
||||
template <typename T>
|
||||
void reduce_1(T const&,
|
||||
image_data_gray8 & out,
|
||||
image_gray8 & out,
|
||||
octree<rgb> /*trees*/[],
|
||||
unsigned /*limits*/[],
|
||||
std::vector<unsigned> & /*alpha*/)
|
||||
|
@ -266,7 +266,7 @@ void reduce_1(T const&,
|
|||
|
||||
template <typename T>
|
||||
void save_as_png(T & file, std::vector<mapnik::rgb> const& palette,
|
||||
mapnik::image_data_gray8 const& image,
|
||||
mapnik::image_gray8 const& image,
|
||||
unsigned width,
|
||||
unsigned height,
|
||||
unsigned color_depth,
|
||||
|
@ -556,7 +556,7 @@ void save_as_png8_oct(T1 & file,
|
|||
if (palette.size() > 16 )
|
||||
{
|
||||
// >16 && <=256 colors -> write 8-bit color depth
|
||||
image_data_gray8 reduced_image(width,height);
|
||||
image_gray8 reduced_image(width,height);
|
||||
reduce_8(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
|
||||
save_as_png(file,palette,reduced_image,width,height,8,alphaTable,opts);
|
||||
}
|
||||
|
@ -565,7 +565,7 @@ void save_as_png8_oct(T1 & file,
|
|||
// 1 color image -> write 1-bit color depth PNG
|
||||
unsigned image_width = ((width + 15) >> 3) & ~1U; // 1-bit image, round up to 16-bit boundary
|
||||
unsigned image_height = height;
|
||||
image_data_gray8 reduced_image(image_width,image_height);
|
||||
image_gray8 reduced_image(image_width,image_height);
|
||||
reduce_1(image,reduced_image,trees, limits, alphaTable);
|
||||
if (meanAlpha<255 && cols[0]==0)
|
||||
{
|
||||
|
@ -579,7 +579,7 @@ void save_as_png8_oct(T1 & file,
|
|||
// <=16 colors -> write 4-bit color depth PNG
|
||||
unsigned image_width = ((width + 7) >> 1) & ~3U; // 4-bit image, round up to 32-bit boundary
|
||||
unsigned image_height = height;
|
||||
image_data_gray8 reduced_image(image_width,image_height);
|
||||
image_gray8 reduced_image(image_width,image_height);
|
||||
reduce_4(image, reduced_image, trees, limits, TRANSPARENCY_LEVELS, alphaTable);
|
||||
save_as_png(file,palette,reduced_image,width,height,4,alphaTable,opts);
|
||||
}
|
||||
|
@ -600,11 +600,11 @@ void save_as_png8(T1 & file,
|
|||
if (palette.size() > 16 )
|
||||
{
|
||||
// >16 && <=256 colors -> write 8-bit color depth
|
||||
image_data_gray8 reduced_image(width, height);
|
||||
image_gray8 reduced_image(width, height);
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::image_data_rgba8::pixel_type const * row = image.getRow(y);
|
||||
mapnik::image_data_gray8::pixel_type * row_out = reduced_image.getRow(y);
|
||||
mapnik::image_rgba8::pixel_type const * row = image.getRow(y);
|
||||
mapnik::image_gray8::pixel_type * row_out = reduced_image.getRow(y);
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
row_out[x] = tree.quantize(row[x]);
|
||||
|
@ -617,7 +617,7 @@ void save_as_png8(T1 & file,
|
|||
// 1 color image -> write 1-bit color depth PNG
|
||||
unsigned image_width = ((width + 15) >> 3) & ~1U; // 1-bit image, round up to 16-bit boundary
|
||||
unsigned image_height = height;
|
||||
image_data_gray8 reduced_image(image_width, image_height);
|
||||
image_gray8 reduced_image(image_width, image_height);
|
||||
reduced_image.set(0);
|
||||
save_as_png(file, palette, reduced_image, width, height, 1, alphaTable, opts);
|
||||
}
|
||||
|
@ -626,11 +626,11 @@ void save_as_png8(T1 & file,
|
|||
// <=16 colors -> write 4-bit color depth PNG
|
||||
unsigned image_width = ((width + 7) >> 1) & ~3U; // 4-bit image, round up to 32-bit boundary
|
||||
unsigned image_height = height;
|
||||
image_data_gray8 reduced_image(image_width, image_height);
|
||||
image_gray8 reduced_image(image_width, image_height);
|
||||
for (unsigned y = 0; y < height; ++y)
|
||||
{
|
||||
mapnik::image_data_rgba8::pixel_type const * row = image.getRow(y);
|
||||
mapnik::image_data_gray8::pixel_type * row_out = reduced_image.getRow(y);
|
||||
mapnik::image_rgba8::pixel_type const * row = image.getRow(y);
|
||||
mapnik::image_gray8::pixel_type * row_out = reduced_image.getRow(y);
|
||||
byte index = 0;
|
||||
for (unsigned x = 0; x < width; ++x)
|
||||
{
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/box2d.hpp>
|
||||
#include <mapnik/image_data_any.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/util/noncopyable.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
// boost
|
||||
|
@ -37,20 +37,17 @@ class raster : private util::noncopyable
|
|||
{
|
||||
public:
|
||||
box2d<double> ext_;
|
||||
image_data_any data_;
|
||||
image_any data_;
|
||||
double filter_factor_;
|
||||
bool premultiplied_alpha_;
|
||||
boost::optional<double> nodata_;
|
||||
|
||||
template <typename ImageData>
|
||||
raster(box2d<double> const& ext,
|
||||
ImageData && data,
|
||||
double filter_factor,
|
||||
bool premultiplied_alpha = false)
|
||||
double filter_factor)
|
||||
: ext_(ext),
|
||||
data_(std::move(data)),
|
||||
filter_factor_(filter_factor),
|
||||
premultiplied_alpha_(premultiplied_alpha) {}
|
||||
filter_factor_(filter_factor) {}
|
||||
|
||||
void set_nodata(double nodata)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
// boost
|
||||
#include <boost/optional.hpp>
|
||||
// boost
|
||||
|
@ -198,7 +198,7 @@ public:
|
|||
colorizer_stops const& get_stops() const { return stops_; }
|
||||
|
||||
template <typename T>
|
||||
void colorize(image_data_rgba8 & out, T const& in, boost::optional<double>const& nodata, feature_impl const& f) const;
|
||||
void colorize(image_rgba8 & out, T const& in, boost::optional<double>const& nodata, feature_impl const& f) const;
|
||||
|
||||
//! \brief Perform the translation of input to output
|
||||
//!
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
#include <mapnik/util/noncopyable.hpp>
|
||||
#include <mapnik/svg/svg_path_adapter.hpp>
|
||||
#include <mapnik/svg/svg_path_attributes.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
|
||||
// agg
|
||||
#include <agg_trans_affine.h>
|
||||
|
@ -130,13 +129,13 @@ struct vector_marker_render_thunk : util::noncopyable
|
|||
|
||||
struct raster_marker_render_thunk : util::noncopyable
|
||||
{
|
||||
image_data_rgba8 & src_;
|
||||
image_rgba8 const& src_;
|
||||
agg::trans_affine tr_;
|
||||
double opacity_;
|
||||
composite_mode_e comp_op_;
|
||||
bool snap_to_pixels_;
|
||||
|
||||
raster_marker_render_thunk(image_data_rgba8 & src,
|
||||
raster_marker_render_thunk(image_rgba8 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
double opacity,
|
||||
composite_mode_e comp_op,
|
||||
|
|
|
@ -32,6 +32,230 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename VD, typename RD, typename RendererType, typename ContextType>
|
||||
struct render_marker_symbolizer_visitor
|
||||
{
|
||||
using vector_dispatch_type = VD;
|
||||
using raster_dispatch_type = RD;
|
||||
using buffer_type = typename std::tuple_element<0,ContextType>::type;
|
||||
|
||||
render_marker_symbolizer_visitor(std::string const& filename,
|
||||
markers_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans,
|
||||
RendererType const& common,
|
||||
box2d<double> const& clip_box,
|
||||
ContextType const& renderer_context)
|
||||
: filename_(filename),
|
||||
sym_(sym),
|
||||
feature_(feature),
|
||||
prj_trans_(prj_trans),
|
||||
common_(common),
|
||||
clip_box_(clip_box),
|
||||
renderer_context_(renderer_context) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const& mark)
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||
double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
||||
double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||
double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
||||
|
||||
// https://github.com/mapnik/mapnik/issues/1316
|
||||
bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename_);
|
||||
|
||||
agg::trans_affine geom_tr;
|
||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
||||
if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
||||
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = mark.get_data();
|
||||
|
||||
// special case for simple ellipse markers
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename_ == "shape://ellipse"
|
||||
&& (has_key(sym_,keys::width) || has_key(sym_,keys::height)))
|
||||
{
|
||||
svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
build_ellipse(sym_, feature_, common_.vars_, *marker_ellipse, svg_path);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
|
||||
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
|
||||
vector_dispatch_type rasterizer_dispatch(marker_ellipse,
|
||||
svg_path,
|
||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
image_tr,
|
||||
sym_,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
snap_to_pixels,
|
||||
renderer_context_);
|
||||
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box_,
|
||||
rasterizer_dispatch,
|
||||
sym_,
|
||||
common_.t_,
|
||||
prj_trans_,
|
||||
geom_tr,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
common_.scale_factor_);
|
||||
if (clip && feature_.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature_.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature_, common_.vars_, converter, sym_);
|
||||
}
|
||||
else
|
||||
{
|
||||
box2d<double> const& bbox = mark.bounding_box();
|
||||
setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature_, common_.vars_, sym_);
|
||||
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym_, feature_, common_.vars_);
|
||||
vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
|
||||
svg_path,
|
||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
image_tr,
|
||||
sym_,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
snap_to_pixels,
|
||||
renderer_context_);
|
||||
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box_,
|
||||
rasterizer_dispatch,
|
||||
sym_,
|
||||
common_.t_,
|
||||
prj_trans_,
|
||||
geom_tr,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
common_.scale_factor_);
|
||||
if (clip && feature_.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature_.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature_, common_.vars_, converter, sym_);
|
||||
}
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& mark)
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
bool clip = get<value_bool, keys::clip>(sym_, feature_, common_.vars_);
|
||||
double offset = get<value_double, keys::offset>(sym_, feature_, common_.vars_);
|
||||
double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym_, feature_, common_.vars_);
|
||||
double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
||||
|
||||
agg::trans_affine geom_tr;
|
||||
auto transform = get_optional<transform_type>(sym_, keys::geometry_transform);
|
||||
if (transform) evaluate_transform(geom_tr, feature_, common_.vars_, *transform, common_.scale_factor_);
|
||||
agg::trans_affine image_tr = agg::trans_affine_scaling(common_.scale_factor_);
|
||||
|
||||
setup_transform_scaling(image_tr, mark.width(), mark.height(), feature_, common_.vars_, sym_);
|
||||
auto image_transform = get_optional<transform_type>(sym_, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature_, common_.vars_, *image_transform);
|
||||
box2d<double> const& bbox = mark.bounding_box();
|
||||
mapnik::image_rgba8 const& marker = mark.get_data();
|
||||
// - clamp sizes to > 4 pixels of interactivity
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * image_tr;
|
||||
raster_dispatch_type rasterizer_dispatch(marker,
|
||||
marker_trans,
|
||||
sym_,
|
||||
*common_.detector_,
|
||||
common_.scale_factor_,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
renderer_context_);
|
||||
|
||||
using vertex_converter_type = vertex_converter<raster_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box_,
|
||||
rasterizer_dispatch,
|
||||
sym_,
|
||||
common_.t_,
|
||||
prj_trans_,
|
||||
geom_tr,
|
||||
feature_,
|
||||
common_.vars_,
|
||||
common_.scale_factor_);
|
||||
|
||||
if (clip && feature_.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature_.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature_, common_.vars_, converter, sym_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string const& filename_;
|
||||
markers_symbolizer const& sym_;
|
||||
mapnik::feature_impl & feature_;
|
||||
proj_transform const& prj_trans_;
|
||||
RendererType const& common_;
|
||||
box2d<double> const& clip_box_;
|
||||
ContextType const& renderer_context_;
|
||||
};
|
||||
|
||||
template <typename VD, typename RD, typename RendererType, typename ContextType>
|
||||
void render_markers_symbolizer(markers_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
|
@ -41,167 +265,18 @@ void render_markers_symbolizer(markers_symbolizer const& sym,
|
|||
ContextType const& renderer_context)
|
||||
{
|
||||
using namespace mapnik::svg;
|
||||
using vector_dispatch_type = VD;
|
||||
using raster_dispatch_type = RD;
|
||||
|
||||
std::string filename = get<std::string>(sym, keys::file, feature, common.vars_, "shape://ellipse");
|
||||
bool clip = get<value_bool, keys::clip>(sym, feature, common.vars_);
|
||||
double offset = get<value_double, keys::offset>(sym, feature, common.vars_);
|
||||
double simplify_tolerance = get<value_double, keys::simplify_tolerance>(sym, feature, common.vars_);
|
||||
double smooth = get<value_double, keys::smooth>(sym, feature, common.vars_);
|
||||
|
||||
// https://github.com/mapnik/mapnik/issues/1316
|
||||
bool snap_to_pixels = !mapnik::marker_cache::instance().is_uri(filename);
|
||||
if (!filename.empty())
|
||||
{
|
||||
boost::optional<marker_ptr> mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
if (mark && *mark)
|
||||
{
|
||||
agg::trans_affine geom_tr;
|
||||
auto transform = get_optional<transform_type>(sym, keys::geometry_transform);
|
||||
if (transform) evaluate_transform(geom_tr, feature, common.vars_, *transform, common.scale_factor_);
|
||||
agg::trans_affine image_tr = agg::trans_affine_scaling(common.scale_factor_);
|
||||
|
||||
if ((*mark)->is_vector())
|
||||
{
|
||||
boost::optional<svg_path_ptr> const& stock_vector_marker = (*mark)->get_vector_data();
|
||||
|
||||
// special case for simple ellipse markers
|
||||
// to allow for full control over rx/ry dimensions
|
||||
if (filename == "shape://ellipse"
|
||||
&& (has_key(sym,keys::width) || has_key(sym,keys::height)))
|
||||
{
|
||||
svg_path_ptr marker_ellipse = std::make_shared<svg_storage_type>();
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_ellipse->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
build_ellipse(sym, feature, common.vars_, *marker_ellipse, svg_path);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform);
|
||||
vector_dispatch_type rasterizer_dispatch(marker_ellipse,
|
||||
svg_path,
|
||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
image_tr,
|
||||
sym,
|
||||
*common.detector_,
|
||||
common.scale_factor_,
|
||||
feature,
|
||||
common.vars_,
|
||||
snap_to_pixels,
|
||||
renderer_context);
|
||||
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, common.vars_, converter, sym);
|
||||
}
|
||||
else
|
||||
{
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
setup_transform_scaling(image_tr, bbox.width(), bbox.height(), feature, common.vars_, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform);
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage((*stock_vector_marker)->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
svg_attribute_type attributes;
|
||||
bool result = push_explicit_style( (*stock_vector_marker)->attributes(), attributes, sym, feature, common.vars_);
|
||||
vector_dispatch_type rasterizer_dispatch(*stock_vector_marker,
|
||||
svg_path,
|
||||
result ? attributes : (*stock_vector_marker)->attributes(),
|
||||
image_tr,
|
||||
sym,
|
||||
*common.detector_,
|
||||
common.scale_factor_,
|
||||
feature,
|
||||
common.vars_,
|
||||
snap_to_pixels,
|
||||
renderer_context);
|
||||
|
||||
using vertex_converter_type = vertex_converter<vector_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, common.vars_, converter, sym);
|
||||
}
|
||||
}
|
||||
else // raster markers
|
||||
{
|
||||
setup_transform_scaling(image_tr, (*mark)->width(), (*mark)->height(), feature, common.vars_, sym);
|
||||
auto image_transform = get_optional<transform_type>(sym, keys::image_transform);
|
||||
if (image_transform) evaluate_transform(image_tr, feature, common.vars_, *image_transform);
|
||||
box2d<double> const& bbox = (*mark)->bounding_box();
|
||||
boost::optional<mapnik::image_ptr> marker = (*mark)->get_bitmap_data();
|
||||
// - clamp sizes to > 4 pixels of interactivity
|
||||
coord2d center = bbox.center();
|
||||
agg::trans_affine_translation recenter(-center.x, -center.y);
|
||||
agg::trans_affine marker_trans = recenter * image_tr;
|
||||
raster_dispatch_type rasterizer_dispatch(**marker,
|
||||
marker_trans,
|
||||
sym,
|
||||
*common.detector_,
|
||||
common.scale_factor_,
|
||||
feature,
|
||||
common.vars_,
|
||||
renderer_context);
|
||||
|
||||
using vertex_converter_type = vertex_converter<raster_dispatch_type,clip_line_tag,
|
||||
clip_poly_tag,
|
||||
transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag, smooth_tag,
|
||||
offset_transform_tag>;
|
||||
vertex_converter_type converter(clip_box, rasterizer_dispatch, sym,common.t_,prj_trans,geom_tr,feature,common.vars_,common.scale_factor_);
|
||||
|
||||
if (clip && feature.paths().size() > 0) // optional clip (default: true)
|
||||
{
|
||||
geometry_type::types type = feature.paths()[0].type();
|
||||
if (type == geometry_type::types::Polygon)
|
||||
converter.template set<clip_poly_tag>();
|
||||
else if (type == geometry_type::types::LineString)
|
||||
converter.template set<clip_line_tag>();
|
||||
}
|
||||
converter.template set<transform_tag>(); //always transform
|
||||
if (std::fabs(offset) > 0.0) converter.template set<offset_transform_tag>(); // parallel offset
|
||||
converter.template set<affine_transform_tag>(); // optional affine transform
|
||||
if (simplify_tolerance > 0.0) converter.template set<simplify_tag>(); // optional simplify converter
|
||||
if (smooth > 0.0) converter.template set<smooth_tag>(); // optional smooth converter
|
||||
apply_markers_multi(feature, common.vars_, converter, sym);
|
||||
}
|
||||
}
|
||||
mapnik::marker const& mark = mapnik::marker_cache::instance().find(filename, true);
|
||||
render_marker_symbolizer_visitor<VD,RD,RendererType,ContextType> visitor(filename,
|
||||
sym,
|
||||
feature,
|
||||
prj_trans,
|
||||
common,
|
||||
clip_box,
|
||||
renderer_context);
|
||||
util::apply_visitor(visitor, mark);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -41,18 +41,18 @@ void render_point_symbolizer(point_symbolizer const &sym,
|
|||
F render_marker)
|
||||
{
|
||||
std::string filename = get<std::string,keys::file>(sym,feature, common.vars_);
|
||||
boost::optional<mapnik::marker_ptr> marker = filename.empty()
|
||||
? std::make_shared<mapnik::marker>()
|
||||
mapnik::marker const& mark = filename.empty()
|
||||
? mapnik::marker(std::move(mapnik::marker_rgba8()))
|
||||
: marker_cache::instance().find(filename, true);
|
||||
|
||||
if (marker)
|
||||
if (!mark.is<mapnik::marker_null>())
|
||||
{
|
||||
value_double opacity = get<value_double,keys::opacity>(sym, feature, common.vars_);
|
||||
value_bool allow_overlap = get<value_bool, keys::allow_overlap>(sym, feature, common.vars_);
|
||||
value_bool ignore_placement = get<value_bool, keys::ignore_placement>(sym, feature, common.vars_);
|
||||
point_placement_enum placement= get<point_placement_enum, keys::point_placement_type>(sym, feature, common.vars_);
|
||||
|
||||
box2d<double> const& bbox = (*marker)->bounding_box();
|
||||
box2d<double> const& bbox = mark.bounding_box();
|
||||
coord2d center = bbox.center();
|
||||
|
||||
agg::trans_affine tr;
|
||||
|
@ -89,7 +89,7 @@ void render_point_symbolizer(point_symbolizer const &sym,
|
|||
{
|
||||
|
||||
render_marker(pixel_position(x, y),
|
||||
**marker,
|
||||
mark,
|
||||
tr,
|
||||
opacity);
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#define MAPNIK_RENDERER_COMMON_PROCESS_RASTER_SYMBOLIZER_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/warp.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
@ -44,10 +45,10 @@ namespace mapnik {
|
|||
namespace detail {
|
||||
|
||||
template <typename F>
|
||||
struct image_data_dispatcher
|
||||
struct image_dispatcher
|
||||
{
|
||||
using composite_function = F;
|
||||
image_data_dispatcher(int start_x, int start_y,
|
||||
image_dispatcher(int start_x, int start_y,
|
||||
int width, int height,
|
||||
double scale_x, double scale_y,
|
||||
scaling_method_e method, double filter_factor,
|
||||
|
@ -68,10 +69,10 @@ struct image_data_dispatcher
|
|||
composite_(composite),
|
||||
nodata_(nodata) {}
|
||||
|
||||
void operator() (image_data_null const& data_in) const {} //no-op
|
||||
void operator() (image_data_rgba8 const& data_in) const
|
||||
void operator() (image_null const& data_in) const {} //no-op
|
||||
void operator() (image_rgba8 const& data_in) const
|
||||
{
|
||||
image_data_rgba8 data_out(width_, height_);
|
||||
image_rgba8 data_out(width_, height_, true, true);
|
||||
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, 0.0, 0.0, filter_factor_);
|
||||
composite_(data_out, comp_op_, opacity_, start_x_, start_y_);
|
||||
}
|
||||
|
@ -79,12 +80,13 @@ struct image_data_dispatcher
|
|||
template <typename T>
|
||||
void operator() (T const& data_in) const
|
||||
{
|
||||
using image_data_type = T;
|
||||
image_data_type data_out(width_, height_);
|
||||
using image_type = T;
|
||||
image_type data_out(width_, height_);
|
||||
scale_image_agg(data_out, data_in, method_, scale_x_, scale_y_, 0.0, 0.0, filter_factor_);
|
||||
image_data_rgba8 dst(width_, height_);
|
||||
image_rgba8 dst(width_, height_);
|
||||
raster_colorizer_ptr colorizer = get<raster_colorizer_ptr>(sym_, keys::colorizer);
|
||||
if (colorizer) colorizer->colorize(dst, data_out, nodata_, feature_);
|
||||
premultiply_alpha(dst);
|
||||
composite_(dst, comp_op_, opacity_, start_x_, start_y_);
|
||||
}
|
||||
private:
|
||||
|
@ -105,10 +107,10 @@ private:
|
|||
};
|
||||
|
||||
template <typename F>
|
||||
struct image_data_warp_dispatcher
|
||||
struct image_warp_dispatcher
|
||||
{
|
||||
using composite_function = F;
|
||||
image_data_warp_dispatcher(proj_transform const& prj_trans,
|
||||
image_warp_dispatcher(proj_transform const& prj_trans,
|
||||
int start_x, int start_y, int width, int height,
|
||||
box2d<double> const& target_ext, box2d<double> const& source_ext,
|
||||
double offset_x, double offset_y, unsigned mesh_size, scaling_method_e scaling_method,
|
||||
|
@ -133,11 +135,11 @@ struct image_data_warp_dispatcher
|
|||
composite_(composite),
|
||||
nodata_(nodata) {}
|
||||
|
||||
void operator() (image_data_null const& data_in) const {} //no-op
|
||||
void operator() (image_null const& data_in) const {} //no-op
|
||||
|
||||
void operator() (image_data_rgba8 const& data_in) const
|
||||
void operator() (image_rgba8 const& data_in) const
|
||||
{
|
||||
image_data_rgba8 data_out(width_, height_);
|
||||
image_rgba8 data_out(width_, height_, true, true);
|
||||
warp_image(data_out, data_in, prj_trans_, target_ext_, source_ext_, offset_x_, offset_y_, mesh_size_, scaling_method_, filter_factor_);
|
||||
composite_(data_out, comp_op_, opacity_, start_x_, start_y_);
|
||||
}
|
||||
|
@ -145,13 +147,14 @@ struct image_data_warp_dispatcher
|
|||
template <typename T>
|
||||
void operator() (T const& data_in) const
|
||||
{
|
||||
using image_data_type = T;
|
||||
image_data_type data_out(width_, height_);
|
||||
using image_type = T;
|
||||
image_type data_out(width_, height_);
|
||||
if (nodata_) data_out.set(*nodata_);
|
||||
warp_image(data_out, data_in, prj_trans_, target_ext_, source_ext_, offset_x_, offset_y_, mesh_size_, scaling_method_, filter_factor_);
|
||||
image_data_rgba8 dst(width_, height_);
|
||||
image_rgba8 dst(width_, height_);
|
||||
raster_colorizer_ptr colorizer = get<raster_colorizer_ptr>(sym_, keys::colorizer);
|
||||
if (colorizer) colorizer->colorize(dst, data_out, nodata_, feature_);
|
||||
premultiply_alpha(dst);
|
||||
composite_(dst, comp_op_, opacity_, start_x_, start_y_);
|
||||
}
|
||||
private:
|
||||
|
@ -202,24 +205,14 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
|||
composite_mode_e comp_op = get<composite_mode_e>(sym, keys::comp_op, feature, common.vars_, src_over);
|
||||
double opacity = get<double>(sym,keys::opacity,feature, common.vars_, 1.0);
|
||||
// only premultiply rgba8 images
|
||||
if (source->data_.is<image_data_rgba8>())
|
||||
if (source->data_.is<image_rgba8>())
|
||||
{
|
||||
bool premultiply_source = !source->premultiplied_alpha_;
|
||||
auto is_premultiplied = get_optional<bool>(sym, keys::premultiplied, feature, common.vars_);
|
||||
if (is_premultiplied)
|
||||
if (is_premultiplied && *is_premultiplied)
|
||||
{
|
||||
if (*is_premultiplied) premultiply_source = false;
|
||||
else premultiply_source = true;
|
||||
}
|
||||
if (premultiply_source)
|
||||
{
|
||||
agg::rendering_buffer buffer(source->data_.getBytes(),
|
||||
source->data_.width(),
|
||||
source->data_.height(),
|
||||
source->data_.width() * 4);
|
||||
agg::pixfmt_rgba32 pixf(buffer);
|
||||
pixf.premultiply();
|
||||
mapnik::set_premultiplied_alpha(source->data_, true);
|
||||
}
|
||||
mapnik::premultiply_alpha(source->data_);
|
||||
}
|
||||
|
||||
if (!prj_trans.equal())
|
||||
|
@ -227,7 +220,7 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
|||
double offset_x = ext.minx() - start_x;
|
||||
double offset_y = ext.miny() - start_y;
|
||||
unsigned mesh_size = static_cast<unsigned>(get<value_integer>(sym,keys::mesh_size,feature, common.vars_, 16));
|
||||
detail::image_data_warp_dispatcher<F> dispatcher(prj_trans, start_x, start_y, raster_width, raster_height,
|
||||
detail::image_warp_dispatcher<F> dispatcher(prj_trans, start_x, start_y, raster_width, raster_height,
|
||||
target_ext, source->ext_, offset_x, offset_y, mesh_size,
|
||||
scaling_method, source->get_filter_factor(),
|
||||
opacity, comp_op, sym, feature, composite, source->nodata());
|
||||
|
@ -243,14 +236,14 @@ void render_raster_symbolizer(raster_symbolizer const& sym,
|
|||
(std::abs(start_x) <= eps) &&
|
||||
(std::abs(start_y) <= eps) )
|
||||
{
|
||||
if (source->data_.is<image_data_rgba8>())
|
||||
if (source->data_.is<image_rgba8>())
|
||||
{
|
||||
composite(util::get<image_data_rgba8>(source->data_), comp_op, opacity, start_x, start_y);
|
||||
composite(util::get<image_rgba8>(source->data_), comp_op, opacity, start_x, start_y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
detail::image_data_dispatcher<F> dispatcher(start_x, start_y, raster_width, raster_height,
|
||||
detail::image_dispatcher<F> dispatcher(start_x, start_y, raster_width, raster_height,
|
||||
image_ratio_x, image_ratio_y,
|
||||
scaling_method, source->get_filter_factor(),
|
||||
opacity, comp_op, sym, feature, composite, source->nodata());
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#ifndef MAPNIK_RENDER_PATTERN_HPP
|
||||
#define MAPNIK_RENDER_PATTERN_HPP
|
||||
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <memory>
|
||||
|
||||
// fwd decl
|
||||
|
@ -35,12 +35,14 @@ namespace mapnik {
|
|||
|
||||
// fwd decl
|
||||
struct rasterizer;
|
||||
class marker;
|
||||
struct marker_svg;
|
||||
|
||||
std::shared_ptr<image_data_rgba8> render_pattern(rasterizer & ras,
|
||||
marker const& marker,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity);
|
||||
template <typename T>
|
||||
void render_pattern(rasterizer & ras,
|
||||
marker_svg const& marker,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity,
|
||||
T & image);
|
||||
|
||||
} // namespace mapnik
|
||||
|
||||
|
|
156
include/mapnik/sse.hpp
Normal file
156
include/mapnik/sse.hpp
Normal file
|
@ -0,0 +1,156 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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_SSE_HPP
|
||||
#define MAPNIK_SSE_HPP
|
||||
|
||||
#include <emmintrin.h>
|
||||
#include <xmmintrin.h>
|
||||
|
||||
#define ROUND_DOWN(x, s) ((x) & ~((s)-1))
|
||||
|
||||
typedef union
|
||||
{
|
||||
__m128i v;
|
||||
int32_t i32[4];
|
||||
uint32_t u32[4];
|
||||
uint16_t u16[8];
|
||||
uint8_t u8[16];
|
||||
} m128_int;
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmple_epu16 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFFFF where x <= y:
|
||||
return _mm_cmpeq_epi16(_mm_subs_epu16(x, y), _mm_setzero_si128());
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmple_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFF where x <= y:
|
||||
return _mm_cmpeq_epi8(_mm_min_epu8(x, y), x);
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmpgt_epu16 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFFFF where x > y:
|
||||
return _mm_andnot_si128(_mm_cmpeq_epi16(x, y), _mm_cmple_epu16(y, x));
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmpgt_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFF where x > y:
|
||||
return _mm_andnot_si128(
|
||||
_mm_cmpeq_epi8(x, y),
|
||||
_mm_cmpeq_epi8(_mm_max_epu8(x, y), x)
|
||||
);
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmplt_epu16 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFFFF where x < y:
|
||||
return _mm_cmpgt_epu16(y, x);
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmplt_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFF where x < y:
|
||||
return _mm_cmpgt_epu8(y, x);
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmpge_epu16 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFFFF where x >= y:
|
||||
return _mm_cmple_epu16(y, x);
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_cmpge_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns 0xFF where x >= y:
|
||||
return _mm_cmple_epu8(y, x);
|
||||
}
|
||||
|
||||
// Its not often that you want to use this!
|
||||
static inline __m128i
|
||||
_mm_not_si128 (__m128i x)
|
||||
{
|
||||
// Returns ~x, the bitwise complement of x:
|
||||
return _mm_xor_si128(x, _mm_cmpeq_epi32(_mm_setzero_si128(), _mm_setzero_si128()));
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_absdiff_epu16 (__m128i x, __m128i y)
|
||||
{
|
||||
// Calculate absolute difference: abs(x - y):
|
||||
return _mm_or_si128(_mm_subs_epu16(x, y), _mm_subs_epu16(y, x));
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_absdiff_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Calculate absolute difference: abs(x - y):
|
||||
return _mm_or_si128(_mm_subs_epu8(x, y), _mm_subs_epu8(y, x));
|
||||
}
|
||||
|
||||
static inline __m128i
|
||||
_mm_div255_epu16 (__m128i x)
|
||||
{
|
||||
// Divide 8 16-bit uints by 255:
|
||||
// x := ((x + 1) + (x >> 8)) >> 8:
|
||||
return _mm_srli_epi16(_mm_adds_epu16(
|
||||
_mm_adds_epu16(x, _mm_set1_epi16(1)),
|
||||
_mm_srli_epi16(x, 8)), 8);
|
||||
}
|
||||
|
||||
static __m128i
|
||||
_mm_scale_epu8 (__m128i x, __m128i y)
|
||||
{
|
||||
// Returns an "alpha blend" of x scaled by y/255;
|
||||
// x := x * (y / 255)
|
||||
// Reorder: x := (x * y) / 255
|
||||
|
||||
// Unpack x and y into 16-bit uints:
|
||||
__m128i xlo = _mm_unpacklo_epi8(x, _mm_setzero_si128());
|
||||
__m128i ylo = _mm_unpacklo_epi8(y, _mm_setzero_si128());
|
||||
__m128i xhi = _mm_unpackhi_epi8(x, _mm_setzero_si128());
|
||||
__m128i yhi = _mm_unpackhi_epi8(y, _mm_setzero_si128());
|
||||
|
||||
// Multiply x with y, keeping the low 16 bits:
|
||||
xlo = _mm_mullo_epi16(xlo, ylo);
|
||||
xhi = _mm_mullo_epi16(xhi, yhi);
|
||||
|
||||
// Divide by 255:
|
||||
xlo = _mm_div255_epu16(xlo);
|
||||
xhi = _mm_div255_epu16(xhi);
|
||||
|
||||
// Repack the 16-bit uints to clamped 8-bit values:
|
||||
return _mm_packus_epi16(xlo, xhi);
|
||||
}
|
||||
|
||||
#endif // MAPNIK_SSE_HPP
|
|
@ -53,7 +53,7 @@ namespace mapnik {
|
|||
class feature_type_style;
|
||||
class label_collision_detector4;
|
||||
class layer;
|
||||
class marker;
|
||||
struct marker;
|
||||
class proj_transform;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,18 +50,20 @@ struct glyph_position
|
|||
|
||||
struct marker_info
|
||||
{
|
||||
marker_info() : marker(), transform() {}
|
||||
marker_info(marker_ptr _marker, agg::trans_affine const& _transform) :
|
||||
//marker_info() : marker(), transform() {}
|
||||
marker_info(marker const& _marker, agg::trans_affine const& _transform) :
|
||||
marker(_marker), transform(_transform) {}
|
||||
marker_ptr marker;
|
||||
marker const& marker;
|
||||
agg::trans_affine transform;
|
||||
};
|
||||
|
||||
using marker_info_ptr = std::shared_ptr<marker_info>;
|
||||
|
||||
/** Stores positions of glphys.
|
||||
*
|
||||
* The actual glyphs and their format are stored in text_layout.
|
||||
*/
|
||||
|
||||
class glyph_positions
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_data_any.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
|
||||
extern "C"
|
||||
|
@ -35,12 +35,13 @@ extern "C"
|
|||
#define RealTIFFClose TIFFClose
|
||||
}
|
||||
|
||||
//std
|
||||
#include <memory>
|
||||
|
||||
#define TIFF_WRITE_SCANLINE 0
|
||||
#define TIFF_WRITE_STRIPPED 1
|
||||
#define TIFF_WRITE_TILED 2
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
static inline tsize_t tiff_write_proc(thandle_t fd, tdata_t buf, tsize_t size)
|
||||
|
@ -181,7 +182,7 @@ struct tiff_config
|
|||
|
||||
struct tag_setter
|
||||
{
|
||||
tag_setter(TIFF * output, tiff_config & config)
|
||||
tag_setter(TIFF * output, tiff_config const& config)
|
||||
: output_(output),
|
||||
config_(config) {}
|
||||
|
||||
|
@ -192,15 +193,22 @@ struct tag_setter
|
|||
throw ImageWriterException("Could not write TIFF - unknown image type provided");
|
||||
}
|
||||
|
||||
inline void operator() (image_data_rgba8 const&) const
|
||||
inline void operator() (image_rgba8 const& data) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 4);
|
||||
//uint16 extras[] = { EXTRASAMPLE_UNASSALPHA };
|
||||
uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
if (data.get_premultiplied())
|
||||
{
|
||||
uint16 extras[] = { EXTRASAMPLE_ASSOCALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
}
|
||||
else
|
||||
{
|
||||
uint16 extras[] = { EXTRASAMPLE_UNASSALPHA };
|
||||
TIFFSetField(output_, TIFFTAG_EXTRASAMPLES, 1, extras);
|
||||
}
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
|
@ -209,7 +217,76 @@ struct tag_setter
|
|||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_data_gray32f const&) const
|
||||
inline void operator() (image_gray64 const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 64);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray64s const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 64);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray64f const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 64);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_FLOATINGPOINT);
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray32 const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 32);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray32s const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 32);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray32f const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
|
||||
|
@ -222,7 +299,7 @@ struct tag_setter
|
|||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_FLOATINGPOINT);
|
||||
}
|
||||
}
|
||||
inline void operator() (image_data_gray16 const&) const
|
||||
inline void operator() (image_gray16 const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
|
@ -236,7 +313,21 @@ struct tag_setter
|
|||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_data_gray8 const&) const
|
||||
inline void operator() (image_gray16s const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 16);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_gray8 const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_UINT);
|
||||
|
@ -250,7 +341,21 @@ struct tag_setter
|
|||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_data_null const&) const
|
||||
inline void operator() (image_gray8s const&) const
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_INT);
|
||||
TIFFSetField(output_, TIFFTAG_BITSPERSAMPLE, 8);
|
||||
TIFFSetField(output_, TIFFTAG_SAMPLESPERPIXEL, 1);
|
||||
if (config_.compression == COMPRESSION_DEFLATE
|
||||
|| config_.compression == COMPRESSION_ADOBE_DEFLATE
|
||||
|| config_.compression == COMPRESSION_LZW)
|
||||
{
|
||||
TIFFSetField(output_, TIFFTAG_PREDICTOR, PREDICTOR_HORIZONTAL);
|
||||
|
||||
}
|
||||
}
|
||||
inline void operator() (image_null const&) const
|
||||
{
|
||||
// Assume this would be null type
|
||||
throw ImageWriterException("Could not write TIFF - Null image provided");
|
||||
|
@ -258,10 +363,10 @@ struct tag_setter
|
|||
|
||||
private:
|
||||
TIFF * output_;
|
||||
tiff_config config_;
|
||||
tiff_config const& config_;
|
||||
};
|
||||
|
||||
void set_tiff_config(TIFF* output, tiff_config & config)
|
||||
inline void set_tiff_config(TIFF* output, tiff_config const& config)
|
||||
{
|
||||
// Set some constant tiff information that doesn't vary based on type of data
|
||||
// or image size
|
||||
|
@ -282,7 +387,7 @@ void set_tiff_config(TIFF* output, tiff_config & config)
|
|||
}
|
||||
|
||||
template <typename T1, typename T2>
|
||||
void save_as_tiff(T1 & file, T2 const& image, tiff_config & config)
|
||||
void save_as_tiff(T1 & file, T2 const& image, tiff_config const& config)
|
||||
{
|
||||
using pixel_type = typename T2::pixel_type;
|
||||
|
||||
|
@ -312,7 +417,6 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config)
|
|||
// Set tags that vary based on the type of data being provided.
|
||||
tag_setter set(output, config);
|
||||
set(image);
|
||||
//util::apply_visitor(set, image);
|
||||
|
||||
// Use specific types of writing methods.
|
||||
if (TIFF_WRITE_SCANLINE == config.method)
|
||||
|
@ -339,9 +443,7 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config)
|
|||
TIFFSetField(output, TIFFTAG_ROWSPERSTRIP, rows_per_strip);
|
||||
std::size_t strip_size = width * rows_per_strip;
|
||||
std::unique_ptr<pixel_type[]> strip_buffer(new pixel_type[strip_size]);
|
||||
int end_y=(height/rows_per_strip+1)*rows_per_strip;
|
||||
|
||||
for (int y=0; y < end_y; y+=rows_per_strip)
|
||||
for (int y=0; y < height; y+=rows_per_strip)
|
||||
{
|
||||
int ty1 = std::min(height, static_cast<int>(y + rows_per_strip)) - y;
|
||||
int row = y;
|
||||
|
@ -380,7 +482,7 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config)
|
|||
TIFFSetField(output, TIFFTAG_TILELENGTH, tile_height);
|
||||
TIFFSetField(output, TIFFTAG_TILEDEPTH, 1);
|
||||
std::size_t tile_size = tile_width * tile_height;
|
||||
std::unique_ptr<pixel_type[]> image_data_out (new pixel_type[tile_size]);
|
||||
std::unique_ptr<pixel_type[]> image_out (new pixel_type[tile_size]);
|
||||
int end_y = (height / tile_height + 1) * tile_height;
|
||||
int end_x = (width / tile_width + 1) * tile_width;
|
||||
end_y = std::min(end_y, height);
|
||||
|
@ -393,14 +495,14 @@ void save_as_tiff(T1 & file, T2 const& image, tiff_config & config)
|
|||
for (int x = 0; x < end_x; x += tile_width)
|
||||
{
|
||||
// Prefill the entire array with zeros.
|
||||
std::fill(image_data_out.get(), image_data_out.get() + tile_size, 0);
|
||||
std::fill(image_out.get(), image_out.get() + tile_size, 0);
|
||||
int tx1 = std::min(width, x + tile_width);
|
||||
int row = y;
|
||||
for (int ty = 0; ty < ty1; ++ty, ++row)
|
||||
{
|
||||
std::copy(image.getRow(row, x), image.getRow(row, tx1), image_data_out.get() + ty * tile_width);
|
||||
std::copy(image.getRow(row, x), image.getRow(row, tx1), image_out.get() + ty * tile_width);
|
||||
}
|
||||
if (TIFFWriteEncodedTile(output, TIFFComputeTile(output, x, y, 0, 0), image_data_out.get(), tile_size * sizeof(pixel_type)) == -1)
|
||||
if (TIFFWriteEncodedTile(output, TIFFComputeTile(output, x, y, 0, 0), image_out.get(), tile_size * sizeof(pixel_type)) == -1)
|
||||
{
|
||||
throw ImageWriterException("Could not write TIFF - TIFF Tile Write failed");
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/config.hpp>
|
||||
#include <mapnik/pixel_types.hpp>
|
||||
|
||||
// icu
|
||||
#include <unicode/uversion.h> // for U_NAMESPACE_QUALIFIER
|
||||
|
@ -42,9 +43,13 @@ namespace mapnik {
|
|||
|
||||
#ifdef BIGINT
|
||||
//using value_integer = boost::long_long_type;
|
||||
using value_integer = long long;
|
||||
//using value_integer = long long;
|
||||
using value_integer = std::int64_t;
|
||||
using value_integer_pixel = gray64s_t;
|
||||
#else
|
||||
using value_integer = int;
|
||||
//using value_integer = int;
|
||||
using value_integer = std::int32_t;
|
||||
using value_integer_pixel = gray32s_t;
|
||||
#endif
|
||||
|
||||
using value_double = double;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#define MAPNIK_WEBP_IO_HPP
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
|
||||
// webp
|
||||
|
@ -73,14 +73,14 @@ std::string webp_encoding_error(WebPEncodingError error)
|
|||
}
|
||||
|
||||
template <typename T2>
|
||||
inline int import_image_data(T2 const& image,
|
||||
inline int import_image(T2 const& im_in,
|
||||
WebPPicture & pic,
|
||||
bool alpha)
|
||||
{
|
||||
image_data<typename T2::pixel_type> const& data = image.data();
|
||||
int stride = sizeof(typename T2::pixel_type) * image.width();
|
||||
if (data.width() == image.width() &&
|
||||
data.height() == image.height())
|
||||
image<typename T2::pixel> const& data = im_in.data();
|
||||
int stride = sizeof(typename T2::pixel_type) * im_in.width();
|
||||
if (data.width() == im_in.width() &&
|
||||
data.height() == im_in.height())
|
||||
{
|
||||
if (alpha)
|
||||
{
|
||||
|
@ -98,11 +98,11 @@ inline int import_image_data(T2 const& image,
|
|||
else
|
||||
{
|
||||
// need to copy: https://github.com/mapnik/mapnik/issues/2024
|
||||
image_data_rgba8 im(image.width(),image.height());
|
||||
for (unsigned y = 0; y < image.height(); ++y)
|
||||
image_rgba8 im(im_in.width(),im_in.height());
|
||||
for (unsigned y = 0; y < im_in.height(); ++y)
|
||||
{
|
||||
typename T2::pixel_type const * row_from = image.getRow(y);
|
||||
image_data_rgba8::pixel_type * row_to = im.getRow(y);
|
||||
typename T2::pixel_type const * row_from = im_in.getRow(y);
|
||||
image_rgba8::pixel_type * row_to = im.getRow(y);
|
||||
std::copy(row_from, row_from + stride, row_to);
|
||||
}
|
||||
if (alpha)
|
||||
|
@ -121,11 +121,11 @@ inline int import_image_data(T2 const& image,
|
|||
}
|
||||
|
||||
template <>
|
||||
inline int import_image_data(image_data_rgba8 const& im,
|
||||
inline int import_image(image_rgba8 const& im,
|
||||
WebPPicture & pic,
|
||||
bool alpha)
|
||||
{
|
||||
int stride = sizeof(image_data_rgba8::pixel_type) * im.width();
|
||||
int stride = sizeof(image_rgba8::pixel_type) * im.width();
|
||||
if (alpha)
|
||||
{
|
||||
return WebPPictureImportRGBA(&pic, im.getBytes(), stride);
|
||||
|
@ -187,10 +187,10 @@ void save_as_webp(T1& file,
|
|||
{
|
||||
// different approach for lossy since ImportYUVAFromRGBA is needed
|
||||
// to prepare WebPPicture and working with view pixels is not viable
|
||||
ok = import_image_data(image,pic,alpha);
|
||||
ok = import_image(image,pic,alpha);
|
||||
}
|
||||
#else
|
||||
ok = import_image_data(image,pic,alpha);
|
||||
ok = import_image(image,pic,alpha);
|
||||
#endif
|
||||
if (!ok)
|
||||
{
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
|
||||
//mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/value_types.hpp>
|
||||
#include <mapnik/xml_tree.hpp>
|
||||
#include <mapnik/enumeration.hpp>
|
||||
#include <mapnik/boolean.hpp>
|
||||
|
@ -87,14 +88,14 @@ struct do_xml_attribute_cast<int>
|
|||
#ifdef BIGINT
|
||||
// specialization for long long
|
||||
template <>
|
||||
struct do_xml_attribute_cast<long long>
|
||||
struct do_xml_attribute_cast<mapnik::value_integer>
|
||||
{
|
||||
static inline boost::optional<long long> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
|
||||
static inline boost::optional<mapnik::value_integer> xml_attribute_cast_impl(xml_tree const& /*tree*/, std::string const& source)
|
||||
{
|
||||
int result;
|
||||
if (mapnik::util::string2int(source, result))
|
||||
return boost::optional<long long>(result);
|
||||
return boost::optional<long long>();
|
||||
return boost::optional<mapnik::value_integer>(result);
|
||||
return boost::optional<mapnik::value_integer>();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -10,4 +10,4 @@ export PYTHONPATH="${CURRENT_DIR}/bindings/python/":$PYTHONPATH
|
|||
export MAPNIK_FONT_DIRECTORY="${CURRENT_DIR}/fonts/dejavu-fonts-ttf-2.34/ttf/"
|
||||
export MAPNIK_INPUT_PLUGINS_DIRECTORY="${CURRENT_DIR}/plugins/input/"
|
||||
export PATH="${CURRENT_DIR}/utils/mapnik-config":${PATH}
|
||||
export PATH="${CURRENT_DIR}/utils/nik2img":${PATH}
|
||||
export PATH="${CURRENT_DIR}/utils/nik2img":${PATH}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include <mapnik/make_unique.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/view_transform.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
|
@ -203,33 +203,99 @@ feature_ptr gdal_featureset::get_feature(mapnik::query const& q)
|
|||
MAPNIK_LOG_DEBUG(gdal) << "gdal_featureset: Reading band=" << band_;
|
||||
if (band_ > 0) // we are querying a single band
|
||||
{
|
||||
mapnik::image_data_gray16 image(im_width, im_height);
|
||||
image.set(std::numeric_limits<std::int16_t>::max());
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||
if (band_ > nbands_)
|
||||
{
|
||||
std::ostringstream s;
|
||||
s << "GDAL Plugin: " << band_ << " is an invalid band, dataset only has " << nbands_ << "bands";
|
||||
throw datasource_exception(s.str());
|
||||
}
|
||||
|
||||
GDALRasterBand * band = dataset_.GetRasterBand(band_);
|
||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
image.getData(), image.width(), image.height(),
|
||||
GDT_Int16, 0, 0);
|
||||
if (raster_io_error == CE_Failure)
|
||||
GDALDataType band_type = band->GetRasterDataType();
|
||||
switch (band_type)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
case GDT_Byte:
|
||||
{
|
||||
mapnik::image_gray8 image(im_width, im_height);
|
||||
image.set(std::numeric_limits<std::uint8_t>::max());
|
||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
image.getData(), image.width(), image.height(),
|
||||
GDT_Byte, 0, 0);
|
||||
if (raster_io_error == CE_Failure)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
||||
// set nodata value to be used in raster colorizer
|
||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||
else raster->set_nodata(raster_nodata);
|
||||
feature->set_raster(raster);
|
||||
break;
|
||||
}
|
||||
case GDT_Float64:
|
||||
case GDT_Float32:
|
||||
{
|
||||
mapnik::image_gray32f image(im_width, im_height);
|
||||
image.set(std::numeric_limits<float>::max());
|
||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
image.getData(), image.width(), image.height(),
|
||||
GDT_Float32, 0, 0);
|
||||
if (raster_io_error == CE_Failure)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
||||
// set nodata value to be used in raster colorizer
|
||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||
else raster->set_nodata(raster_nodata);
|
||||
feature->set_raster(raster);
|
||||
break;
|
||||
}
|
||||
case GDT_UInt16:
|
||||
{
|
||||
mapnik::image_gray16 image(im_width, im_height);
|
||||
image.set(std::numeric_limits<std::uint16_t>::max());
|
||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
image.getData(), image.width(), image.height(),
|
||||
GDT_UInt16, 0, 0);
|
||||
if (raster_io_error == CE_Failure)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
||||
// set nodata value to be used in raster colorizer
|
||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||
else raster->set_nodata(raster_nodata);
|
||||
feature->set_raster(raster);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case GDT_Int16:
|
||||
{
|
||||
mapnik::image_gray16s image(im_width, im_height);
|
||||
image.set(std::numeric_limits<std::int16_t>::max());
|
||||
raster_nodata = band->GetNoDataValue(&raster_has_nodata);
|
||||
raster_io_error = band->RasterIO(GF_Read, x_off, y_off, width, height,
|
||||
image.getData(), image.width(), image.height(),
|
||||
GDT_Int16, 0, 0);
|
||||
if (raster_io_error == CE_Failure)
|
||||
{
|
||||
throw datasource_exception(CPLGetLastErrorMsg());
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
||||
// set nodata value to be used in raster colorizer
|
||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||
else raster->set_nodata(raster_nodata);
|
||||
feature->set_raster(raster);
|
||||
break;
|
||||
}
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, image, filter_factor);
|
||||
// set nodata value to be used in raster colorizer
|
||||
if (nodata_value_) raster->set_nodata(*nodata_value_);
|
||||
else raster->set_nodata(raster_nodata);
|
||||
feature->set_raster(raster);
|
||||
}
|
||||
else // working with all bands
|
||||
{
|
||||
mapnik::image_data_rgba8 image(im_width, im_height);
|
||||
mapnik::image_rgba8 image(im_width, im_height);
|
||||
image.set(std::numeric_limits<std::uint32_t>::max());
|
||||
for (int i = 0; i < nbands_; ++i)
|
||||
{
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
#include <mapnik/feature_factory.hpp>
|
||||
#include <mapnik/view_transform.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/util/trim.hpp>
|
||||
#include <mapnik/global.hpp> // for int2net
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/view_transform.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/conversions.hpp>
|
||||
#include <mapnik/util/trim.hpp>
|
||||
#include <mapnik/box2d.hpp> // for box2d
|
||||
|
@ -183,12 +183,7 @@ mapnik::raster_ptr read_data_band(mapnik::box2d<double> const& bbox,
|
|||
uint16_t width, uint16_t height,
|
||||
bool hasnodata, T reader)
|
||||
{
|
||||
mapnik::image_data_gray32f image(width, height);
|
||||
//image.set(std::numeric_limits<float>::max());
|
||||
// Start with plain white (ABGR or RGBA depending on endiannes)
|
||||
// TODO: set to transparent instead?
|
||||
image.set(0xffffffff);
|
||||
|
||||
mapnik::image_gray32f image(width, height);
|
||||
float* data = image.getData();
|
||||
double val;
|
||||
val = reader(); // nodata value, need to read anyway
|
||||
|
@ -199,7 +194,7 @@ mapnik::raster_ptr read_data_band(mapnik::box2d<double> const& bbox,
|
|||
data[off] = val;
|
||||
}
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0, true);
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);
|
||||
if ( hasnodata ) raster->set_nodata(val);
|
||||
return raster;
|
||||
}
|
||||
|
@ -271,7 +266,7 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
|
|||
uint16_t width, uint16_t height,
|
||||
bool hasnodata, T reader)
|
||||
{
|
||||
mapnik::image_data_rgba8 image(width,height);
|
||||
mapnik::image_rgba8 image(width,height, true, true);
|
||||
// Start with plain white (ABGR or RGBA depending on endiannes)
|
||||
// TODO: set to transparent instead?
|
||||
image.set(0xffffffff);
|
||||
|
@ -279,7 +274,7 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
|
|||
|
||||
int val;
|
||||
uint8_t * data = image.getBytes();
|
||||
int ps = 4; // sizeof(image_data::pixel_type)
|
||||
int ps = 4; // sizeof(image::pixel_type)
|
||||
int off;
|
||||
val = reader(); // nodata value, need to read anyway
|
||||
for (int y=0; y<height; ++y) {
|
||||
|
@ -292,7 +287,7 @@ mapnik::raster_ptr read_grayscale_band(mapnik::box2d<double> const& bbox,
|
|||
data[off+2] = val;
|
||||
}
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0, true);
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0);
|
||||
if ( hasnodata ) raster->set_nodata(val);
|
||||
return raster;
|
||||
}
|
||||
|
@ -352,9 +347,9 @@ mapnik::raster_ptr pgraster_wkb_reader::read_grayscale(mapnik::box2d<double> con
|
|||
mapnik::raster_ptr pgraster_wkb_reader::read_rgba(mapnik::box2d<double> const& bbox,
|
||||
uint16_t width, uint16_t height)
|
||||
{
|
||||
mapnik::image_data_rgba8 image(width, height);
|
||||
mapnik::image_rgba8 im(width, height, true, true);
|
||||
// Start with plain white (ABGR or RGBA depending on endiannes)
|
||||
image.set(0xffffffff);
|
||||
im.set(0xffffffff);
|
||||
|
||||
uint8_t nodataval;
|
||||
for (int bn=0; bn<numBands_; ++bn) {
|
||||
|
@ -387,8 +382,8 @@ mapnik::raster_ptr pgraster_wkb_reader::read_rgba(mapnik::box2d<double> const& b
|
|||
<< " nodataval " << tmp << " != band 0 nodataval " << nodataval;
|
||||
}
|
||||
|
||||
int ps = 4; // sizeof(image_data::pixel_type)
|
||||
uint8_t * image_data = image.getBytes();
|
||||
int ps = 4; // sizeof(image::pixel_type)
|
||||
uint8_t * image_data = im.getBytes();
|
||||
for (int y=0; y<height_; ++y) {
|
||||
for (int x=0; x<width_; ++x) {
|
||||
uint8_t val = read_uint8(&ptr_);
|
||||
|
@ -400,7 +395,7 @@ mapnik::raster_ptr pgraster_wkb_reader::read_rgba(mapnik::box2d<double> const& b
|
|||
}
|
||||
}
|
||||
}
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, image, 1.0, true);
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(bbox, im, 1.0);
|
||||
raster->set_nodata(0xffffffff);
|
||||
return raster;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/view_transform.hpp>
|
||||
#include <mapnik/image_reader.hpp>
|
||||
|
@ -43,7 +43,7 @@
|
|||
using mapnik::query;
|
||||
using mapnik::image_reader;
|
||||
using mapnik::feature_ptr;
|
||||
using mapnik::image_data_rgba8;
|
||||
using mapnik::image_rgba8;
|
||||
using mapnik::raster;
|
||||
using mapnik::feature_factory;
|
||||
|
||||
|
@ -114,9 +114,8 @@ feature_ptr raster_featureset<LookupPolicy>::next()
|
|||
rem.maxx() + x_off + width,
|
||||
rem.maxy() + y_off + height);
|
||||
intersect = t.backward(feature_raster_extent);
|
||||
mapnik::image_data_any data = reader->read(x_off, y_off, width, height);
|
||||
mapnik::image_any data = reader->read(x_off, y_off, width, height);
|
||||
mapnik::raster_ptr raster = std::make_shared<mapnik::raster>(intersect, std::move(data), 1.0);
|
||||
raster->premultiplied_alpha_ = reader->premultiplied_alpha();
|
||||
feature->set_raster(raster);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/query.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
|
@ -114,10 +114,9 @@ feature_ptr rasterlite_featureset::get_feature(mapnik::query const& q)
|
|||
{
|
||||
if (size > 0)
|
||||
{
|
||||
mapnik::image_data_rgba8 image(width,height);
|
||||
mapnik::image_rgba8 image(width,height);
|
||||
unsigned char* raster_data = static_cast<unsigned char*>(raster);
|
||||
unsigned char* image_data = image.getBytes();
|
||||
std::memcpy(image_data, raster_data, size);
|
||||
std::memcpy(image.getBytes(), raster_data, size);
|
||||
feature->set_raster(std::make_shared<mapnik::raster>(intersect, std::move(image), 1.0));
|
||||
MAPNIK_LOG_DEBUG(rasterlite) << "rasterlite_featureset: Done";
|
||||
}
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/rule.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/layer.hpp>
|
||||
|
@ -43,6 +42,7 @@
|
|||
#include <mapnik/image_compositing.hpp>
|
||||
#include <mapnik/image_filter.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
// agg
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
|
@ -108,9 +108,52 @@ agg_renderer<T0,T1>::agg_renderer(Map const& m, T0 & pixmap, std::shared_ptr<T1>
|
|||
setup(m);
|
||||
}
|
||||
|
||||
template <typename buffer_type>
|
||||
struct setup_agg_bg_visitor
|
||||
{
|
||||
setup_agg_bg_visitor(buffer_type & pixmap,
|
||||
renderer_common const& common,
|
||||
composite_mode_e mode,
|
||||
double opacity)
|
||||
: pixmap_(pixmap),
|
||||
common_(common),
|
||||
mode_(mode),
|
||||
opacity_(opacity) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const&) {}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
mapnik::image_rgba8 const& bg_image = marker.get_data();
|
||||
int w = bg_image.width();
|
||||
int h = bg_image.height();
|
||||
if ( w > 0 && h > 0)
|
||||
{
|
||||
// repeat background-image both vertically and horizontally
|
||||
unsigned x_steps = static_cast<unsigned>(std::ceil(common_.width_/double(w)));
|
||||
unsigned y_steps = static_cast<unsigned>(std::ceil(common_.height_/double(h)));
|
||||
for (unsigned x=0;x<x_steps;++x)
|
||||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
composite(pixmap_, bg_image, mode_, opacity_, x*w, y*h);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
private:
|
||||
buffer_type & pixmap_;
|
||||
renderer_common const& common_;
|
||||
composite_mode_e mode_;
|
||||
double opacity_;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::setup(Map const &m)
|
||||
{
|
||||
mapnik::set_premultiplied_alpha(pixmap_, true);
|
||||
boost::optional<color> const& bg = m.background();
|
||||
if (bg)
|
||||
{
|
||||
|
@ -118,11 +161,13 @@ void agg_renderer<T0,T1>::setup(Map const &m)
|
|||
{
|
||||
mapnik::color bg_color = *bg;
|
||||
bg_color.premultiply();
|
||||
pixmap_.set_background(bg_color);
|
||||
mapnik::fill(pixmap_, bg_color);
|
||||
}
|
||||
else
|
||||
{
|
||||
pixmap_.set_background(*bg);
|
||||
mapnik::color bg_color = *bg;
|
||||
bg_color.set_premultiplied(true);
|
||||
mapnik::fill(pixmap_,bg_color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -130,26 +175,12 @@ void agg_renderer<T0,T1>::setup(Map const &m)
|
|||
if (image_filename)
|
||||
{
|
||||
// NOTE: marker_cache returns premultiplied image, if needed
|
||||
boost::optional<mapnik::marker_ptr> bg_marker = mapnik::marker_cache::instance().find(*image_filename,true);
|
||||
if (bg_marker && (*bg_marker)->is_bitmap())
|
||||
{
|
||||
mapnik::image_ptr bg_image = *(*bg_marker)->get_bitmap_data();
|
||||
int w = bg_image->width();
|
||||
int h = bg_image->height();
|
||||
if ( w > 0 && h > 0)
|
||||
{
|
||||
// repeat background-image both vertically and horizontally
|
||||
unsigned x_steps = static_cast<unsigned>(std::ceil(common_.width_/double(w)));
|
||||
unsigned y_steps = static_cast<unsigned>(std::ceil(common_.height_/double(h)));
|
||||
for (unsigned x=0;x<x_steps;++x)
|
||||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
composite(pixmap_.data(),*bg_image, m.background_image_comp_op(), m.background_image_opacity(), x*w, y*h, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mapnik::marker const& bg_marker = mapnik::marker_cache::instance().find(*image_filename,true);
|
||||
setup_agg_bg_visitor<buffer_type> visitor(pixmap_,
|
||||
common_,
|
||||
m.background_image_comp_op(),
|
||||
m.background_image_opacity());
|
||||
util::apply_visitor(visitor, bg_marker);
|
||||
}
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: Scale=" << m.scale();
|
||||
}
|
||||
|
@ -167,10 +198,7 @@ void agg_renderer<T0,T1>::start_map_processing(Map const& map)
|
|||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::end_map_processing(Map const& )
|
||||
{
|
||||
|
||||
agg::rendering_buffer buf(pixmap_.raw_data(),common_.width_,common_.height_, common_.width_ * 4);
|
||||
agg::pixfmt_rgba32_pre pixf(buf);
|
||||
pixf.demultiply();
|
||||
mapnik::demultiply_alpha(pixmap_);
|
||||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End map processing";
|
||||
}
|
||||
|
||||
|
@ -239,7 +267,7 @@ void agg_renderer<T0,T1>::start_style_processing(feature_type_style const& st)
|
|||
}
|
||||
else
|
||||
{
|
||||
internal_buffer_->set_background(color(0,0,0,0)); // fill with transparent colour
|
||||
mapnik::fill(*internal_buffer_, 0); // fill with transparent colour
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -250,12 +278,13 @@ void agg_renderer<T0,T1>::start_style_processing(feature_type_style const& st)
|
|||
}
|
||||
else
|
||||
{
|
||||
internal_buffer_->set_background(color(0,0,0,0)); // fill with transparent colour
|
||||
mapnik::fill(*internal_buffer_, 0); // fill with transparent colour
|
||||
}
|
||||
common_.t_.set_offset(0);
|
||||
ras_ptr->clip_box(0,0,common_.width_,common_.height_);
|
||||
}
|
||||
current_buffer_ = internal_buffer_.get();
|
||||
set_premultiplied_alpha(*current_buffer_,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -274,7 +303,7 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
|
|||
if (st.image_filters().size() > 0)
|
||||
{
|
||||
blend_from = true;
|
||||
mapnik::filter::filter_visitor<image_32> visitor(*current_buffer_);
|
||||
mapnik::filter::filter_visitor<buffer_type> visitor(*current_buffer_);
|
||||
for (mapnik::filter::filter_type const& filter_tag : st.image_filters())
|
||||
{
|
||||
util::apply_visitor(visitor, filter_tag);
|
||||
|
@ -282,21 +311,21 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
|
|||
}
|
||||
if (st.comp_op())
|
||||
{
|
||||
composite(pixmap_.data(), current_buffer_->data(),
|
||||
composite(pixmap_, *current_buffer_,
|
||||
*st.comp_op(), st.get_opacity(),
|
||||
-common_.t_.offset(),
|
||||
-common_.t_.offset(), false);
|
||||
-common_.t_.offset());
|
||||
}
|
||||
else if (blend_from || st.get_opacity() < 1.0)
|
||||
{
|
||||
composite(pixmap_.data(), current_buffer_->data(),
|
||||
composite(pixmap_, *current_buffer_,
|
||||
src_over, st.get_opacity(),
|
||||
-common_.t_.offset(),
|
||||
-common_.t_.offset(), false);
|
||||
-common_.t_.offset());
|
||||
}
|
||||
}
|
||||
// apply any 'direct' image filters
|
||||
mapnik::filter::filter_visitor<image_32> visitor(pixmap_);
|
||||
mapnik::filter::filter_visitor<buffer_type> visitor(pixmap_);
|
||||
for (mapnik::filter::filter_type const& filter_tag : st.direct_image_filters())
|
||||
{
|
||||
util::apply_visitor(visitor, filter_tag);
|
||||
|
@ -304,87 +333,128 @@ void agg_renderer<T0,T1>::end_style_processing(feature_type_style const& st)
|
|||
MAPNIK_LOG_DEBUG(agg_renderer) << "agg_renderer: End processing style";
|
||||
}
|
||||
|
||||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
||||
marker const& marker,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity,
|
||||
composite_mode_e comp_op)
|
||||
template <typename buffer_type>
|
||||
struct agg_render_marker_visitor
|
||||
{
|
||||
using color_type = agg::rgba8;
|
||||
using order_type = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
|
||||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
|
||||
using svg_attribute_type = agg::pod_bvector<mapnik::svg::path_attributes>;
|
||||
agg_render_marker_visitor(renderer_common & common,
|
||||
buffer_type * current_buffer,
|
||||
std::unique_ptr<rasterizer> const& ras_ptr,
|
||||
gamma_method_enum & gamma_method,
|
||||
double & gamma,
|
||||
pixel_position const& pos,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity,
|
||||
composite_mode_e comp_op)
|
||||
: common_(common),
|
||||
current_buffer_(current_buffer),
|
||||
ras_ptr_(ras_ptr),
|
||||
gamma_method_(gamma_method),
|
||||
gamma_(gamma),
|
||||
pos_(pos),
|
||||
tr_(tr),
|
||||
opacity_(opacity),
|
||||
comp_op_(comp_op) {}
|
||||
|
||||
ras_ptr->reset();
|
||||
if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0)
|
||||
{
|
||||
ras_ptr->gamma(agg::gamma_power());
|
||||
gamma_method_ = GAMMA_POWER;
|
||||
gamma_ = 1.0;
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),
|
||||
current_buffer_->width(),
|
||||
current_buffer_->height(),
|
||||
current_buffer_->width() * 4);
|
||||
pixfmt_comp_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(comp_op));
|
||||
renderer_base renb(pixf);
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
if (marker.is_vector())
|
||||
void operator() (marker_svg const& marker)
|
||||
{
|
||||
box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
|
||||
using color_type = agg::rgba8;
|
||||
using order_type = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
|
||||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
|
||||
using svg_attribute_type = agg::pod_bvector<mapnik::svg::path_attributes>;
|
||||
|
||||
ras_ptr_->reset();
|
||||
if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0)
|
||||
{
|
||||
ras_ptr_->gamma(agg::gamma_power());
|
||||
gamma_method_ = GAMMA_POWER;
|
||||
gamma_ = 1.0;
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),
|
||||
current_buffer_->width(),
|
||||
current_buffer_->height(),
|
||||
current_buffer_->getRowSize());
|
||||
pixfmt_comp_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(comp_op_));
|
||||
renderer_base renb(pixf);
|
||||
|
||||
box2d<double> const& bbox = marker.get_data()->bounding_box();
|
||||
coord<double,2> c = bbox.center();
|
||||
// center the svg marker on '0,0'
|
||||
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
|
||||
// apply symbol transformation to get to map space
|
||||
mtx *= tr;
|
||||
mtx *= tr_;
|
||||
mtx *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
// render the marker at the center of the marker box
|
||||
mtx.translate(pos.x, pos.y);
|
||||
mtx.translate(pos_.x, pos_.y);
|
||||
using namespace mapnik::svg;
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage((*marker.get_vector_data())->source());
|
||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker.get_data()->source());
|
||||
svg_path_adapter svg_path(stl_storage);
|
||||
svg_renderer_agg<svg_path_adapter,
|
||||
svg_attribute_type,
|
||||
renderer_type,
|
||||
pixfmt_comp_type> svg_renderer(svg_path,
|
||||
(*marker.get_vector_data())->attributes());
|
||||
marker.get_data()->attributes());
|
||||
|
||||
// https://github.com/mapnik/mapnik/issues/1316
|
||||
// https://github.com/mapnik/mapnik/issues/1866
|
||||
mtx.tx = std::floor(mtx.tx+.5);
|
||||
mtx.ty = std::floor(mtx.ty+.5);
|
||||
svg_renderer.render(*ras_ptr, sl, renb, mtx, opacity, bbox);
|
||||
svg_renderer.render(*ras_ptr_, sl, renb, mtx, opacity_, bbox);
|
||||
}
|
||||
else
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
double width = (*marker.get_bitmap_data())->width();
|
||||
double height = (*marker.get_bitmap_data())->height();
|
||||
using color_type = agg::rgba8;
|
||||
using order_type = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<color_type, order_type>; // comp blender
|
||||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
using renderer_type = agg::renderer_scanline_aa_solid<renderer_base>;
|
||||
using svg_attribute_type = agg::pod_bvector<mapnik::svg::path_attributes>;
|
||||
|
||||
ras_ptr_->reset();
|
||||
if (gamma_method_ != GAMMA_POWER || gamma_ != 1.0)
|
||||
{
|
||||
ras_ptr_->gamma(agg::gamma_power());
|
||||
gamma_method_ = GAMMA_POWER;
|
||||
gamma_ = 1.0;
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),
|
||||
current_buffer_->width(),
|
||||
current_buffer_->height(),
|
||||
current_buffer_->getRowSize());
|
||||
pixfmt_comp_type pixf(buf);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(comp_op_));
|
||||
renderer_base renb(pixf);
|
||||
|
||||
double width = marker.width();
|
||||
double height = marker.height();
|
||||
if (std::fabs(1.0 - common_.scale_factor_) < 0.001
|
||||
&& (std::fabs(1.0 - tr.sx) < agg::affine_epsilon)
|
||||
&& (std::fabs(0.0 - tr.shy) < agg::affine_epsilon)
|
||||
&& (std::fabs(0.0 - tr.shx) < agg::affine_epsilon)
|
||||
&& (std::fabs(1.0 - tr.sy) < agg::affine_epsilon))
|
||||
&& (std::fabs(1.0 - tr_.sx) < agg::affine_epsilon)
|
||||
&& (std::fabs(0.0 - tr_.shy) < agg::affine_epsilon)
|
||||
&& (std::fabs(0.0 - tr_.shx) < agg::affine_epsilon)
|
||||
&& (std::fabs(1.0 - tr_.sy) < agg::affine_epsilon))
|
||||
{
|
||||
double cx = 0.5 * width;
|
||||
double cy = 0.5 * height;
|
||||
composite(current_buffer_->data(), **marker.get_bitmap_data(),
|
||||
comp_op, opacity,
|
||||
std::floor(pos.x - cx + .5),
|
||||
std::floor(pos.y - cy + .5),
|
||||
false);
|
||||
composite(*current_buffer_, marker.get_data(),
|
||||
comp_op_, opacity_,
|
||||
std::floor(pos_.x - cx + .5),
|
||||
std::floor(pos_.y - cy + .5));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
double p[8];
|
||||
double x0 = pos.x - 0.5 * width;
|
||||
double y0 = pos.y - 0.5 * height;
|
||||
double x0 = pos_.x - 0.5 * width;
|
||||
double y0 = pos_.y - 0.5 * height;
|
||||
p[0] = x0; p[1] = y0;
|
||||
p[2] = x0 + width; p[3] = y0;
|
||||
p[4] = x0 + width; p[5] = y0 + height;
|
||||
|
@ -392,31 +462,31 @@ void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
|||
|
||||
agg::trans_affine marker_tr;
|
||||
|
||||
marker_tr *= agg::trans_affine_translation(-pos.x,-pos.y);
|
||||
marker_tr *= tr;
|
||||
marker_tr *= agg::trans_affine_translation(-pos_.x,-pos_.y);
|
||||
marker_tr *= tr_;
|
||||
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
marker_tr *= agg::trans_affine_translation(pos.x,pos.y);
|
||||
marker_tr *= agg::trans_affine_translation(pos_.x,pos_.y);
|
||||
|
||||
marker_tr.transform(&p[0], &p[1]);
|
||||
marker_tr.transform(&p[2], &p[3]);
|
||||
marker_tr.transform(&p[4], &p[5]);
|
||||
marker_tr.transform(&p[6], &p[7]);
|
||||
|
||||
ras_ptr->move_to_d(p[0],p[1]);
|
||||
ras_ptr->line_to_d(p[2],p[3]);
|
||||
ras_ptr->line_to_d(p[4],p[5]);
|
||||
ras_ptr->line_to_d(p[6],p[7]);
|
||||
ras_ptr_->move_to_d(p[0],p[1]);
|
||||
ras_ptr_->line_to_d(p[2],p[3]);
|
||||
ras_ptr_->line_to_d(p[4],p[5]);
|
||||
ras_ptr_->line_to_d(p[6],p[7]);
|
||||
|
||||
|
||||
agg::span_allocator<color_type> sa;
|
||||
agg::image_filter_bilinear filter_kernel;
|
||||
agg::image_filter_lut filter(filter_kernel, false);
|
||||
|
||||
image_data_rgba8 const& src = **marker.get_bitmap_data();
|
||||
buffer_type const& src = marker.get_data();
|
||||
agg::rendering_buffer marker_buf((unsigned char *)src.getBytes(),
|
||||
src.width(),
|
||||
src.height(),
|
||||
src.width()*4);
|
||||
src.getRowSize());
|
||||
agg::pixfmt_rgba32_pre marker_pixf(marker_buf);
|
||||
using img_accessor_type = agg::image_accessor_clone<agg::pixfmt_rgba32_pre>;
|
||||
using interpolator_type = agg::span_interpolator_linear<agg::trans_affine>;
|
||||
|
@ -431,10 +501,41 @@ void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
|||
final_tr.ty = std::floor(final_tr.ty+.5);
|
||||
interpolator_type interpolator(final_tr);
|
||||
span_gen_type sg(ia, interpolator, filter);
|
||||
renderer_type rp(renb,sa, sg, unsigned(opacity*255));
|
||||
agg::render_scanlines(*ras_ptr, sl, rp);
|
||||
renderer_type rp(renb,sa, sg, unsigned(opacity_*255));
|
||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common & common_;
|
||||
buffer_type * current_buffer_;
|
||||
std::unique_ptr<rasterizer> const& ras_ptr_;
|
||||
gamma_method_enum & gamma_method_;
|
||||
double & gamma_;
|
||||
pixel_position const& pos_;
|
||||
agg::trans_affine const& tr_;
|
||||
double opacity_;
|
||||
composite_mode_e comp_op_;
|
||||
|
||||
};
|
||||
|
||||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::render_marker(pixel_position const& pos,
|
||||
marker const& marker,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity,
|
||||
composite_mode_e comp_op)
|
||||
{
|
||||
agg_render_marker_visitor<buffer_type> visitor(common_,
|
||||
current_buffer_,
|
||||
ras_ptr,
|
||||
gamma_method_,
|
||||
gamma_,
|
||||
pos,
|
||||
tr,
|
||||
opacity,
|
||||
comp_op);
|
||||
util::apply_visitor(visitor, marker);
|
||||
}
|
||||
|
||||
template <typename T0, typename T1>
|
||||
|
@ -453,10 +554,10 @@ template <typename T0, typename T1>
|
|||
void agg_renderer<T0,T1>::debug_draw_box(box2d<double> const& box,
|
||||
double x, double y, double angle)
|
||||
{
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),
|
||||
current_buffer_->width(),
|
||||
current_buffer_->height(),
|
||||
current_buffer_->width() * 4);
|
||||
current_buffer_->getRowSize());
|
||||
debug_draw_box(buf, box, x, y, angle);
|
||||
}
|
||||
|
||||
|
@ -509,19 +610,19 @@ void agg_renderer<T0,T1>::draw_geo_extent(box2d<double> const& extent, mapnik::c
|
|||
unsigned rgba = color.rgba();
|
||||
for (double x=x0; x<x1; x++)
|
||||
{
|
||||
pixmap_.setPixel(x, y0, rgba);
|
||||
pixmap_.setPixel(x, y1, rgba);
|
||||
mapnik::set_pixel(pixmap_, x, y0, rgba);
|
||||
mapnik::set_pixel(pixmap_, x, y1, rgba);
|
||||
}
|
||||
for (double y=y0; y<y1; y++)
|
||||
{
|
||||
pixmap_.setPixel(x0, y, rgba);
|
||||
pixmap_.setPixel(x1, y, rgba);
|
||||
mapnik::set_pixel(pixmap_, x0, y, rgba);
|
||||
mapnik::set_pixel(pixmap_, x1, y, rgba);
|
||||
}
|
||||
}
|
||||
|
||||
template class agg_renderer<image_32>;
|
||||
template void agg_renderer<image_32>::debug_draw_box<agg::rendering_buffer>(
|
||||
template class agg_renderer<image_rgba8>;
|
||||
template void agg_renderer<image_rgba8>::debug_draw_box<agg::rendering_buffer>(
|
||||
agg::rendering_buffer& buf,
|
||||
box2d<double> const& box,
|
||||
double x, double y, double angle);
|
||||
}
|
||||
} // end ns
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/make_unique.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
@ -58,7 +58,7 @@ void agg_renderer<T0,T1>::process(building_symbolizer const& sym,
|
|||
using ren_base = agg::renderer_base<agg::pixfmt_rgba32_pre>;
|
||||
using renderer = agg::renderer_scanline_aa_solid<ren_base>;
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
|
||||
agg::pixfmt_rgba32_pre pixf(buf);
|
||||
ren_base renb(pixf);
|
||||
|
||||
|
@ -115,8 +115,7 @@ void agg_renderer<T0,T1>::process(building_symbolizer const& sym,
|
|||
});
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(building_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(building_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
}
|
||||
|
|
|
@ -23,13 +23,15 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/label_collision_detector.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
void draw_rect(image_32 &pixmap, box2d<double> const& box)
|
||||
template <typename T>
|
||||
void draw_rect(T &pixmap, box2d<double> const& box)
|
||||
{
|
||||
int x0 = static_cast<int>(box.minx());
|
||||
int x1 = static_cast<int>(box.maxx());
|
||||
|
@ -38,13 +40,13 @@ void draw_rect(image_32 &pixmap, box2d<double> const& box)
|
|||
unsigned color1 = 0xff0000ff;
|
||||
for (int x=x0; x<x1; x++)
|
||||
{
|
||||
pixmap.setPixel(x, y0, color1);
|
||||
pixmap.setPixel(x, y1, color1);
|
||||
mapnik::set_pixel(pixmap, x, y0, color1);
|
||||
mapnik::set_pixel(pixmap, x, y1, color1);
|
||||
}
|
||||
for (int y=y0; y<y1; y++)
|
||||
{
|
||||
pixmap.setPixel(x0, y, color1);
|
||||
pixmap.setPixel(x1, y, color1);
|
||||
mapnik::set_pixel(pixmap, x0, y, color1);
|
||||
mapnik::set_pixel(pixmap, x1, y, color1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -80,17 +82,17 @@ void agg_renderer<T0,T1>::process(debug_symbolizer const& sym,
|
|||
if (cmd == SEG_CLOSE) continue;
|
||||
prj_trans.backward(x,y,z);
|
||||
common_.t_.forward(&x,&y);
|
||||
pixmap_.setPixel(x,y,0xff0000ff);
|
||||
pixmap_.setPixel(x-1,y-1,0xff0000ff);
|
||||
pixmap_.setPixel(x+1,y+1,0xff0000ff);
|
||||
pixmap_.setPixel(x-1,y+1,0xff0000ff);
|
||||
pixmap_.setPixel(x+1,y-1,0xff0000ff);
|
||||
mapnik::set_pixel(pixmap_,x,y,0xff0000ff);
|
||||
mapnik::set_pixel(pixmap_,x-1,y-1,0xff0000ff);
|
||||
mapnik::set_pixel(pixmap_,x+1,y+1,0xff0000ff);
|
||||
mapnik::set_pixel(pixmap_,x-1,y+1,0xff0000ff);
|
||||
mapnik::set_pixel(pixmap_,x+1,y-1,0xff0000ff);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(debug_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(debug_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/symbolizer_keys.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/vertex.hpp>
|
||||
#include <mapnik/renderer_common.hpp>
|
||||
#include <mapnik/proj_transform.hpp>
|
||||
|
@ -70,7 +70,7 @@ void agg_renderer<T0,T1>::process(dot_symbolizer const& sym,
|
|||
double opacity = get<double>(sym, keys::opacity, feature, common_.vars_, 1.0);
|
||||
color const& fill = get<mapnik::color>(sym, keys::fill, feature, common_.vars_, mapnik::color(128,128,128));
|
||||
ras_ptr->reset();
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(),current_buffer_->width() * 4);
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(),current_buffer_->getRowSize());
|
||||
using blender_type = agg::comp_op_adaptor_rgba_pre<agg::rgba8, agg::order_rgba>;
|
||||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
|
@ -102,7 +102,7 @@ void agg_renderer<T0,T1>::process(dot_symbolizer const& sym,
|
|||
}
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(dot_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(dot_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/agg_render_marker.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/util/variant.hpp>
|
||||
#include <mapnik/text/renderer.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
|
@ -48,9 +49,14 @@ namespace mapnik {
|
|||
* to render it, and the boxes themselves should already be
|
||||
* in the detector from the placement_finder.
|
||||
*/
|
||||
struct thunk_renderer
|
||||
|
||||
template <typename T>
|
||||
struct thunk_renderer;
|
||||
|
||||
template <>
|
||||
struct thunk_renderer<image_rgba8>
|
||||
{
|
||||
using renderer_type = agg_renderer<image_32>;
|
||||
using renderer_type = agg_renderer<image_rgba8>;
|
||||
using buffer_type = renderer_type::buffer_type;
|
||||
using text_renderer_type = agg_text_renderer<buffer_type>;
|
||||
|
||||
|
@ -75,7 +81,7 @@ struct thunk_renderer
|
|||
renderer_type,
|
||||
pixfmt_comp_type>;
|
||||
ras_ptr_->reset();
|
||||
buf_type render_buffer(buf_->raw_data(), buf_->width(), buf_->height(), buf_->width() * 4);
|
||||
buf_type render_buffer(buf_->getBytes(), buf_->width(), buf_->height(), buf_->getRowSize());
|
||||
pixfmt_comp_type pixf(render_buffer);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(thunk.comp_op_));
|
||||
renderer_base renb(pixf);
|
||||
|
@ -96,7 +102,7 @@ struct thunk_renderer
|
|||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
|
||||
ras_ptr_->reset();
|
||||
buf_type render_buffer(buf_->raw_data(), buf_->width(), buf_->height(), buf_->width() * 4);
|
||||
buf_type render_buffer(buf_->getBytes(), buf_->width(), buf_->height(), buf_->getRowSize());
|
||||
pixfmt_comp_type pixf(render_buffer);
|
||||
pixf.comp_op(static_cast<agg::comp_op_e>(thunk.comp_op_));
|
||||
renderer_base renb(pixf);
|
||||
|
@ -119,7 +125,7 @@ struct thunk_renderer
|
|||
if (glyphs->marker())
|
||||
{
|
||||
ren_.render_marker(glyphs->marker_pos(),
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->marker,
|
||||
glyphs->marker()->transform,
|
||||
thunk.opacity_, thunk.comp_op_);
|
||||
}
|
||||
|
@ -130,7 +136,7 @@ struct thunk_renderer
|
|||
template <typename T>
|
||||
void operator()(T const &) const
|
||||
{
|
||||
// TODO: warning if unimplemented?
|
||||
throw std::runtime_error("Rendering of this data type is not supported currently by the renderer");
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -150,7 +156,7 @@ void agg_renderer<T0,T1>::process(group_symbolizer const& sym,
|
|||
sym, feature, common_.vars_, prj_trans, clipping_extent(common_), common_,
|
||||
[&](render_thunk_list const& thunks, pixel_position const& render_offset)
|
||||
{
|
||||
thunk_renderer ren(*this, ras_ptr, current_buffer_, common_, render_offset);
|
||||
thunk_renderer<buffer_type> ren(*this, ras_ptr, current_buffer_, common_, render_offset);
|
||||
for (render_thunk_ptr const& thunk : thunks)
|
||||
{
|
||||
util::apply_visitor(ren, *thunk);
|
||||
|
@ -158,7 +164,7 @@ void agg_renderer<T0,T1>::process(group_symbolizer const& sym,
|
|||
});
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(group_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(group_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/agg_pattern_source.hpp>
|
||||
|
@ -52,100 +52,204 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename buffer_type>
|
||||
struct agg_renderer_process_visitor_l
|
||||
{
|
||||
agg_renderer_process_visitor_l(renderer_common & common,
|
||||
buffer_type & pixmap,
|
||||
buffer_type * current_buffer,
|
||||
std::unique_ptr<rasterizer> const& ras_ptr,
|
||||
line_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
: common_(common),
|
||||
pixmap_(pixmap),
|
||||
current_buffer_(current_buffer),
|
||||
ras_ptr_(ras_ptr),
|
||||
sym_(sym),
|
||||
feature_(feature),
|
||||
prj_trans_(prj_trans) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const& marker)
|
||||
{
|
||||
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);
|
||||
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_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
|
||||
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);
|
||||
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());
|
||||
double half_stroke = marker.width()/2.0;
|
||||
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);
|
||||
}
|
||||
|
||||
vertex_converter<rasterizer_type, clip_line_tag, transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag,smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box,ras,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for (geometry_type const& geom : feature_.paths())
|
||||
{
|
||||
if (geom.size() > 1)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
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_);
|
||||
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_);
|
||||
value_double smooth = get<value_double, keys::smooth>(sym_, feature_, common_.vars_);
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
|
||||
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);
|
||||
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());
|
||||
double half_stroke = marker.width()/2.0;
|
||||
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);
|
||||
}
|
||||
|
||||
vertex_converter<rasterizer_type, clip_line_tag, transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag,smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box,ras,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for (geometry_type const& geom : feature_.paths())
|
||||
{
|
||||
if (geom.size() > 1)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common & common_;
|
||||
buffer_type & pixmap_;
|
||||
buffer_type * current_buffer_;
|
||||
std::unique_ptr<rasterizer> const& ras_ptr_;
|
||||
line_pattern_symbolizer const& sym_;
|
||||
mapnik::feature_impl & feature_;
|
||||
proj_transform const& prj_trans_;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
{
|
||||
|
||||
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>;
|
||||
|
||||
std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_);
|
||||
if (filename.empty()) return;
|
||||
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
|
||||
if (!marker_ptr || !(*marker_ptr)) return;
|
||||
boost::optional<image_ptr> pat;
|
||||
// TODO - re-implement at renderer level like polygon_pattern symbolizer
|
||||
value_double opacity = get<value_double, keys::opacity>(sym, feature, common_.vars_);
|
||||
if ((*marker_ptr)->is_bitmap())
|
||||
{
|
||||
pat = (*marker_ptr)->get_bitmap_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, 1.0);
|
||||
}
|
||||
|
||||
if (!pat) return;
|
||||
|
||||
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_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
|
||||
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(*(*pat), opacity);
|
||||
pattern_type pattern (filter,source);
|
||||
renderer_type ren(ren_base, pattern);
|
||||
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());
|
||||
double half_stroke = (*marker_ptr)->width()/2.0;
|
||||
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);
|
||||
}
|
||||
|
||||
vertex_converter<rasterizer_type, clip_line_tag, transform_tag,
|
||||
affine_transform_tag,
|
||||
simplify_tag,smooth_tag,
|
||||
offset_transform_tag>
|
||||
converter(clip_box,ras,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (clip) converter.set<clip_line_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for (geometry_type const& geom : feature.paths())
|
||||
{
|
||||
if (geom.size() > 1)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
mapnik::marker const & marker = marker_cache::instance().find(filename, true);
|
||||
agg_renderer_process_visitor_l<buffer_type> visitor(common_,
|
||||
pixmap_,
|
||||
current_buffer_,
|
||||
ras_ptr,
|
||||
sym,
|
||||
feature,
|
||||
prj_trans);
|
||||
util::apply_visitor(visitor, marker);
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(line_pattern_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(line_pattern_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
@ -109,7 +109,7 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
|
|||
gamma_ = gamma;
|
||||
}
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
|
||||
|
||||
using color_type = agg::rgba8;
|
||||
using order_type = agg::order_rgba;
|
||||
|
@ -225,7 +225,7 @@ void agg_renderer<T0,T1>::process(line_symbolizer const& sym,
|
|||
}
|
||||
|
||||
|
||||
template void agg_renderer<image_32>::process(line_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(line_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
@ -125,7 +124,7 @@ struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detec
|
|||
using pixfmt_comp_type = agg::pixfmt_custom_blend_rgba<blender_type, BufferType>;
|
||||
using renderer_base = agg::renderer_base<pixfmt_comp_type>;
|
||||
|
||||
raster_markers_rasterizer_dispatch(image_data_rgba8 & src,
|
||||
raster_markers_rasterizer_dispatch(image_rgba8 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
symbolizer_base const& sym,
|
||||
Detector & detector,
|
||||
|
@ -148,6 +147,8 @@ struct raster_markers_rasterizer_dispatch : public raster_markers_dispatch<Detec
|
|||
|
||||
void render_marker(agg::trans_affine const& marker_tr, double opacity)
|
||||
{
|
||||
// In the long term this should be a visitor pattern based on the type of render this->src_ provided that converts
|
||||
// the destination pixel type required.
|
||||
render_raster_marker(renb_, ras_, this->src_, marker_tr, opacity, this->scale_factor_, snap_to_pixels_);
|
||||
}
|
||||
|
||||
|
@ -191,7 +192,7 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
|||
gamma_ = gamma;
|
||||
}
|
||||
|
||||
buf_type render_buffer(current_buffer_->raw_data(), current_buffer_->width(), current_buffer_->height(), current_buffer_->width() * 4);
|
||||
buf_type render_buffer(current_buffer_->getBytes(), current_buffer_->width(), current_buffer_->height(), current_buffer_->getRowSize());
|
||||
box2d<double> clip_box = clipping_extent(common_);
|
||||
|
||||
auto renderer_context = std::tie(render_buffer,*ras_ptr,pixmap_);
|
||||
|
@ -203,7 +204,7 @@ void agg_renderer<T0,T1>::process(markers_symbolizer const& sym,
|
|||
sym, feature, prj_trans, common_, clip_box, renderer_context);
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(markers_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(markers_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/geom_util.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/marker.hpp>
|
||||
|
@ -59,7 +60,7 @@ void agg_renderer<T0,T1>::process(point_symbolizer const& sym,
|
|||
});
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(point_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(point_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
|
@ -54,6 +53,254 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
template <typename buffer_type>
|
||||
struct agg_renderer_process_visitor_p
|
||||
{
|
||||
agg_renderer_process_visitor_p(renderer_common & common,
|
||||
buffer_type * current_buffer,
|
||||
std::unique_ptr<rasterizer> const& ras_ptr,
|
||||
gamma_method_enum & gamma_method,
|
||||
double & gamma,
|
||||
polygon_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
proj_transform const& prj_trans)
|
||||
: common_(common),
|
||||
current_buffer_(current_buffer),
|
||||
ras_ptr_(ras_ptr),
|
||||
gamma_method_(gamma_method),
|
||||
gamma_(gamma),
|
||||
sym_(sym),
|
||||
feature_(feature),
|
||||
prj_trans_(prj_trans) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const& marker)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
using clipped_geometry_type = agg::conv_clip_polygon<vertex_adapter>;
|
||||
using path_type = transform_path_adapter<view_transform,clipped_geometry_type>;
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->getRowSize());
|
||||
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.getBytes(),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;
|
||||
if (feature_.num_geometries() > 0)
|
||||
{
|
||||
vertex_adapter va(feature_.get_geometry(0));
|
||||
clipped_geometry_type clipped(va);
|
||||
clipped.clip_box(clip_box.minx(),clip_box.miny(),clip_box.maxx(),clip_box.maxy());
|
||||
path_type path(common_.t_,clipped,prj_trans_);
|
||||
path.vertex(&x0,&y0);
|
||||
}
|
||||
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_);
|
||||
|
||||
vertex_converter<rasterizer, clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag>
|
||||
converter(clip_box,*ras_ptr_,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for ( geometry_type const& geom : feature_.paths())
|
||||
{
|
||||
if (geom.size() > 2)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
ras_ptr_->filling_rule(agg::fill_even_odd);
|
||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
using clipped_geometry_type = agg::conv_clip_polygon<vertex_adapter>;
|
||||
using path_type = transform_path_adapter<view_transform,clipped_geometry_type>;
|
||||
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();
|
||||
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->getRowSize());
|
||||
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_);
|
||||
|
||||
|
||||
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.getBytes(),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;
|
||||
if (feature_.num_geometries() > 0)
|
||||
{
|
||||
vertex_adapter va(feature_.get_geometry(0));
|
||||
clipped_geometry_type clipped(va);
|
||||
clipped.clip_box(clip_box.minx(),clip_box.miny(),clip_box.maxx(),clip_box.maxy());
|
||||
path_type path(common_.t_,clipped,prj_trans_);
|
||||
path.vertex(&x0,&y0);
|
||||
}
|
||||
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_);
|
||||
|
||||
vertex_converter<rasterizer, clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag>
|
||||
converter(clip_box,*ras_ptr_,sym_,common_.t_,prj_trans_,tr,feature_,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (prj_trans_.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for ( geometry_type const& geom : feature_.paths())
|
||||
{
|
||||
if (geom.size() > 2)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
ras_ptr_->filling_rule(agg::fill_even_odd);
|
||||
agg::render_scanlines(*ras_ptr_, sl, rp);
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common & common_;
|
||||
buffer_type * current_buffer_;
|
||||
std::unique_ptr<rasterizer> const& ras_ptr_;
|
||||
gamma_method_enum & gamma_method_;
|
||||
double & gamma_;
|
||||
polygon_pattern_symbolizer const& sym_;
|
||||
mapnik::feature_impl & feature_;
|
||||
proj_transform const& prj_trans_;
|
||||
};
|
||||
|
||||
template <typename T0, typename T1>
|
||||
void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
|
@ -61,128 +308,20 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
|
|||
{
|
||||
std::string filename = get<std::string, keys::file>(sym, feature, common_.vars_);
|
||||
if (filename.empty()) return;
|
||||
boost::optional<mapnik::marker_ptr> marker_ptr = marker_cache::instance().find(filename, true);
|
||||
if (!marker_ptr || !(*marker_ptr)) return;
|
||||
|
||||
boost::optional<image_ptr> pat;
|
||||
|
||||
if ((*marker_ptr)->is_bitmap())
|
||||
{
|
||||
pat = (*marker_ptr)->get_bitmap_data();
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
pat = render_pattern(*ras_ptr, **marker_ptr, image_tr, 1.0);
|
||||
}
|
||||
|
||||
if (!pat) return;
|
||||
|
||||
using clipped_geometry_type = agg::conv_clip_polygon<vertex_adapter>;
|
||||
using path_type = transform_path_adapter<view_transform,clipped_geometry_type>;
|
||||
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(), current_buffer_->width(),
|
||||
current_buffer_->height(), current_buffer_->width() * 4);
|
||||
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=(*pat)->width();
|
||||
unsigned h=(*pat)->height();
|
||||
agg::rendering_buffer pattern_rbuf((agg::int8u*)(*pat)->getBytes(),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;
|
||||
if (feature.num_geometries() > 0)
|
||||
{
|
||||
vertex_adapter va(feature.get_geometry(0));
|
||||
clipped_geometry_type clipped(va);
|
||||
clipped.clip_box(clip_box.minx(),clip_box.miny(),clip_box.maxx(),clip_box.maxy());
|
||||
path_type path(common_.t_,clipped,prj_trans);
|
||||
path.vertex(&x0,&y0);
|
||||
}
|
||||
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_);
|
||||
|
||||
vertex_converter<rasterizer, clip_poly_tag,transform_tag,affine_transform_tag,simplify_tag,smooth_tag>
|
||||
converter(clip_box,*ras_ptr,sym,common_.t_,prj_trans,tr,feature,common_.vars_,common_.scale_factor_);
|
||||
|
||||
if (prj_trans.equal() && clip) converter.set<clip_poly_tag>(); //optional clip (default: true)
|
||||
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
|
||||
|
||||
for ( geometry_type const& geom : feature.paths())
|
||||
{
|
||||
if (geom.size() > 2)
|
||||
{
|
||||
vertex_adapter va(geom);
|
||||
converter.apply(va);
|
||||
}
|
||||
}
|
||||
agg::scanline_u8 sl;
|
||||
ras_ptr->filling_rule(agg::fill_even_odd);
|
||||
agg::render_scanlines(*ras_ptr, sl, rp);
|
||||
mapnik::marker const& marker = marker_cache::instance().find(filename, true);
|
||||
agg_renderer_process_visitor_p<buffer_type> visitor(common_,
|
||||
current_buffer_,
|
||||
ras_ptr,
|
||||
gamma_method_,
|
||||
gamma_,
|
||||
sym,
|
||||
feature,
|
||||
prj_trans);
|
||||
util::apply_visitor(visitor, marker);
|
||||
}
|
||||
|
||||
|
||||
template void agg_renderer<image_32>::process(polygon_pattern_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(polygon_pattern_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_helpers.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
|
@ -62,7 +61,7 @@ void agg_renderer<T0,T1>::process(polygon_symbolizer const& sym,
|
|||
}
|
||||
|
||||
box2d<double> clip_box = clipping_extent(common_);
|
||||
agg::rendering_buffer buf(current_buffer_->raw_data(),current_buffer_->width(),current_buffer_->height(), current_buffer_->width() * 4);
|
||||
agg::rendering_buffer buf(current_buffer_->getBytes(),current_buffer_->width(),current_buffer_->height(), current_buffer_->getRowSize());
|
||||
|
||||
render_polygon_symbolizer<vertex_converter_type>(
|
||||
sym, feature, prj_trans, common_, clip_box, *ras_ptr,
|
||||
|
@ -88,7 +87,7 @@ void agg_renderer<T0,T1>::process(polygon_symbolizer const& sym,
|
|||
});
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(polygon_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(polygon_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -25,11 +25,10 @@
|
|||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/image_scaling.hpp>
|
||||
#include <mapnik/image_compositing.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/symbolizer.hpp>
|
||||
#include <mapnik/raster_colorizer.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/image_data.hpp>
|
||||
#include <mapnik/image.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/raster.hpp>
|
||||
#include <mapnik/box2d.hpp>
|
||||
|
@ -52,15 +51,15 @@ void agg_renderer<T0,T1>::process(raster_symbolizer const& sym,
|
|||
{
|
||||
render_raster_symbolizer(
|
||||
sym, feature, prj_trans, common_,
|
||||
[&](image_data_rgba8 & target, composite_mode_e comp_op, double opacity,
|
||||
[&](image_rgba8 & target, composite_mode_e comp_op, double opacity,
|
||||
int start_x, int start_y) {
|
||||
composite(current_buffer_->data(), target,
|
||||
comp_op, opacity, start_x, start_y, false);
|
||||
composite(*current_buffer_, target,
|
||||
comp_op, opacity, start_x, start_y);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(raster_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(raster_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/text/symbolizer_helpers.hpp>
|
||||
#include <mapnik/pixel_position.hpp>
|
||||
|
@ -65,7 +64,7 @@ void agg_renderer<T0,T1>::process(shield_symbolizer const& sym,
|
|||
{
|
||||
if (glyphs->marker())
|
||||
render_marker(glyphs->marker_pos(),
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->marker,
|
||||
glyphs->marker()->transform,
|
||||
opacity, comp_op);
|
||||
ren.render(*glyphs);
|
||||
|
@ -73,7 +72,7 @@ void agg_renderer<T0,T1>::process(shield_symbolizer const& sym,
|
|||
}
|
||||
|
||||
|
||||
template void agg_renderer<image_32>::process(shield_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(shield_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
// mapnik
|
||||
#include <mapnik/feature.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
#include <mapnik/agg_rasterizer.hpp>
|
||||
#include <mapnik/text/symbolizer_helpers.hpp>
|
||||
#include <mapnik/text/renderer.hpp>
|
||||
|
@ -75,7 +75,7 @@ void agg_renderer<T0,T1>::process(text_symbolizer const& sym,
|
|||
}
|
||||
}
|
||||
|
||||
template void agg_renderer<image_32>::process(text_symbolizer const&,
|
||||
template void agg_renderer<image_rgba8>::process(text_symbolizer const&,
|
||||
mapnik::feature_impl &,
|
||||
proj_transform const&);
|
||||
|
||||
|
|
|
@ -152,6 +152,7 @@ source = Split(
|
|||
miniz_png.cpp
|
||||
color.cpp
|
||||
conversions.cpp
|
||||
image_copy.cpp
|
||||
image_compositing.cpp
|
||||
image_scaling.cpp
|
||||
box2d.cpp
|
||||
|
@ -170,10 +171,14 @@ source = Split(
|
|||
font_set.cpp
|
||||
function_call.cpp
|
||||
gradient.cpp
|
||||
graphics.cpp
|
||||
parse_path.cpp
|
||||
image_reader.cpp
|
||||
cairo_io.cpp
|
||||
image_util.cpp
|
||||
image_util_jpeg.cpp
|
||||
image_util_png.cpp
|
||||
image_util_tiff.cpp
|
||||
image_util_webp.cpp
|
||||
layer.cpp
|
||||
map.cpp
|
||||
load_map.cpp
|
||||
|
|
|
@ -337,7 +337,7 @@ void cairo_context::set_gradient(cairo_gradient const& pattern, const box2d<doub
|
|||
check_object_status_and_throw_exception(*this);
|
||||
}
|
||||
|
||||
void cairo_context::add_image(double x, double y, image_data_rgba8 & data, double opacity)
|
||||
void cairo_context::add_image(double x, double y, image_rgba8 const& data, double opacity)
|
||||
{
|
||||
cairo_pattern pattern(data);
|
||||
pattern.set_origin(x, y);
|
||||
|
@ -348,7 +348,7 @@ void cairo_context::add_image(double x, double y, image_data_rgba8 & data, doubl
|
|||
check_object_status_and_throw_exception(*this);
|
||||
}
|
||||
|
||||
void cairo_context::add_image(agg::trans_affine const& tr, image_data_rgba8 & data, double opacity)
|
||||
void cairo_context::add_image(agg::trans_affine const& tr, image_rgba8 const& data, double opacity)
|
||||
{
|
||||
cairo_pattern pattern(data);
|
||||
if (!tr.is_identity())
|
||||
|
|
|
@ -99,6 +99,42 @@ cairo_renderer<T>::cairo_renderer(Map const& m,
|
|||
template <typename T>
|
||||
cairo_renderer<T>::~cairo_renderer() {}
|
||||
|
||||
struct setup_marker_visitor
|
||||
{
|
||||
setup_marker_visitor(cairo_context & context, renderer_common const& common)
|
||||
: context_(context), common_(common) {}
|
||||
|
||||
void operator() (marker_null const &) {}
|
||||
void operator() (marker_svg const &) {}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
mapnik::image_rgba8 const& bg_image = marker.get_data();
|
||||
int w = bg_image.width();
|
||||
int h = bg_image.height();
|
||||
if ( w > 0 && h > 0)
|
||||
{
|
||||
// repeat background-image both vertically and horizontally
|
||||
unsigned x_steps = unsigned(std::ceil(common_.width_/double(w)));
|
||||
unsigned y_steps = unsigned(std::ceil(common_.height_/double(h)));
|
||||
for (unsigned x=0;x<x_steps;++x)
|
||||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
agg::trans_affine matrix = agg::trans_affine_translation(
|
||||
x*w,
|
||||
y*h);
|
||||
context_.add_image(matrix, bg_image, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
cairo_context & context_;
|
||||
renderer_common const& common_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void cairo_renderer<T>::setup(Map const& map)
|
||||
{
|
||||
|
@ -113,29 +149,8 @@ void cairo_renderer<T>::setup(Map const& map)
|
|||
if (image_filename)
|
||||
{
|
||||
// NOTE: marker_cache returns premultiplied image, if needed
|
||||
boost::optional<mapnik::marker_ptr> bg_marker = mapnik::marker_cache::instance().find(*image_filename,true);
|
||||
if (bg_marker && (*bg_marker)->is_bitmap())
|
||||
{
|
||||
mapnik::image_ptr bg_image = *(*bg_marker)->get_bitmap_data();
|
||||
int w = bg_image->width();
|
||||
int h = bg_image->height();
|
||||
if ( w > 0 && h > 0)
|
||||
{
|
||||
// repeat background-image both vertically and horizontally
|
||||
unsigned x_steps = unsigned(std::ceil(common_.width_/double(w)));
|
||||
unsigned y_steps = unsigned(std::ceil(common_.height_/double(h)));
|
||||
for (unsigned x=0;x<x_steps;++x)
|
||||
{
|
||||
for (unsigned y=0;y<y_steps;++y)
|
||||
{
|
||||
agg::trans_affine matrix = agg::trans_affine_translation(
|
||||
x*w,
|
||||
y*h);
|
||||
context_.add_image(matrix, *bg_image, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mapnik::marker const& bg_marker = mapnik::marker_cache::instance().find(*image_filename,true);
|
||||
util::apply_visitor(setup_marker_visitor(context_, common_), bg_marker);
|
||||
}
|
||||
MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer: Scale=" << map.scale();
|
||||
}
|
||||
|
@ -187,6 +202,68 @@ void cairo_renderer<T>::end_style_processing(feature_type_style const& st)
|
|||
MAPNIK_LOG_DEBUG(cairo_renderer) << "cairo_renderer:end style processing";
|
||||
}
|
||||
|
||||
struct cairo_render_marker_visitor
|
||||
{
|
||||
cairo_render_marker_visitor(cairo_context & context,
|
||||
renderer_common const& common,
|
||||
pixel_position const& pos,
|
||||
agg::trans_affine const& tr,
|
||||
double opacity,
|
||||
bool recenter)
|
||||
: context_(context),
|
||||
common_(common),
|
||||
pos_(pos),
|
||||
tr_(tr),
|
||||
opacity_(opacity),
|
||||
recenter_(recenter) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const& marker)
|
||||
{
|
||||
mapnik::svg_path_ptr vmarker = marker.get_data();
|
||||
if (vmarker)
|
||||
{
|
||||
box2d<double> bbox = vmarker->bounding_box();
|
||||
agg::trans_affine marker_tr = tr_;
|
||||
if (recenter_)
|
||||
{
|
||||
coord<double,2> c = bbox.center();
|
||||
marker_tr = agg::trans_affine_translation(-c.x,-c.y);
|
||||
marker_tr *= tr_;
|
||||
}
|
||||
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
|
||||
svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
|
||||
svg::svg_path_adapter svg_path(stl_storage);
|
||||
marker_tr.translate(pos_.x, pos_.y);
|
||||
render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity_);
|
||||
}
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
double width = marker.get_data().width();
|
||||
double height = marker.get_data().height();
|
||||
double cx = 0.5 * width;
|
||||
double cy = 0.5 * height;
|
||||
agg::trans_affine marker_tr;
|
||||
marker_tr *= agg::trans_affine_translation(-cx,-cy);
|
||||
marker_tr *= tr_;
|
||||
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
marker_tr *= agg::trans_affine_translation(pos_.x,pos_.y);
|
||||
context_.add_image(marker_tr, marker.get_data(), opacity_);
|
||||
}
|
||||
|
||||
private:
|
||||
cairo_context & context_;
|
||||
renderer_common const& common_;
|
||||
pixel_position const& pos_;
|
||||
agg::trans_affine const& tr_;
|
||||
double opacity_;
|
||||
bool recenter_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void cairo_renderer<T>::render_marker(pixel_position const& pos,
|
||||
marker const& marker,
|
||||
|
@ -196,40 +273,13 @@ void cairo_renderer<T>::render_marker(pixel_position const& pos,
|
|||
|
||||
{
|
||||
cairo_save_restore guard(context_);
|
||||
if (marker.is_vector())
|
||||
{
|
||||
mapnik::svg_path_ptr vmarker = *marker.get_vector_data();
|
||||
if (vmarker)
|
||||
{
|
||||
box2d<double> bbox = vmarker->bounding_box();
|
||||
agg::trans_affine marker_tr = tr;
|
||||
if (recenter)
|
||||
{
|
||||
coord<double,2> c = bbox.center();
|
||||
marker_tr = agg::trans_affine_translation(-c.x,-c.y);
|
||||
marker_tr *= tr;
|
||||
}
|
||||
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
agg::pod_bvector<svg::path_attributes> const & attributes = vmarker->attributes();
|
||||
svg::vertex_stl_adapter<svg::svg_path_storage> stl_storage(vmarker->source());
|
||||
svg::svg_path_adapter svg_path(stl_storage);
|
||||
marker_tr.translate(pos.x, pos.y);
|
||||
render_vector_marker(context_, svg_path, attributes, bbox, marker_tr, opacity);
|
||||
}
|
||||
}
|
||||
else if (marker.is_bitmap())
|
||||
{
|
||||
double width = (*marker.get_bitmap_data())->width();
|
||||
double height = (*marker.get_bitmap_data())->height();
|
||||
double cx = 0.5 * width;
|
||||
double cy = 0.5 * height;
|
||||
agg::trans_affine marker_tr;
|
||||
marker_tr *= agg::trans_affine_translation(-cx,-cy);
|
||||
marker_tr *= tr;
|
||||
marker_tr *= agg::trans_affine_scaling(common_.scale_factor_);
|
||||
marker_tr *= agg::trans_affine_translation(pos.x,pos.y);
|
||||
context_.add_image(marker_tr, **marker.get_bitmap_data(), opacity);
|
||||
}
|
||||
cairo_render_marker_visitor visitor(context_,
|
||||
common_,
|
||||
pos,
|
||||
tr,
|
||||
opacity,
|
||||
recenter);
|
||||
util::apply_visitor(visitor, marker);
|
||||
}
|
||||
|
||||
template class cairo_renderer<cairo_ptr>;
|
||||
|
|
|
@ -77,7 +77,7 @@ struct thunk_renderer
|
|||
thunk.opacity_);
|
||||
}
|
||||
|
||||
void operator()(raster_marker_render_thunk const &thunk) const
|
||||
void operator()(raster_marker_render_thunk const& thunk) const
|
||||
{
|
||||
cairo_save_restore guard(context_);
|
||||
context_.set_operator(thunk.comp_op_);
|
||||
|
@ -100,7 +100,7 @@ struct thunk_renderer
|
|||
if (glyphs->marker())
|
||||
{
|
||||
ren_.render_marker(glyphs->marker_pos(),
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->marker,
|
||||
glyphs->marker()->transform,
|
||||
thunk.opacity_, thunk.comp_op_);
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ struct thunk_renderer
|
|||
template <typename T0>
|
||||
void operator()(T0 const &) const
|
||||
{
|
||||
// TODO: warning if unimplemented?
|
||||
throw std::runtime_error("Rendering of this type is not supported by the cairo renderer.");
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
@ -36,6 +36,53 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
struct cairo_renderer_process_visitor_l
|
||||
{
|
||||
cairo_renderer_process_visitor_l(renderer_common const& common,
|
||||
line_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
unsigned & width,
|
||||
unsigned & height)
|
||||
: common_(common),
|
||||
sym_(sym),
|
||||
feature_(feature),
|
||||
width_(width),
|
||||
height_(height) {}
|
||||
|
||||
std::shared_ptr<cairo_pattern> operator() (mapnik::marker_null const&)
|
||||
{
|
||||
throw std::runtime_error("This should not have been reached.");
|
||||
}
|
||||
|
||||
std::shared_ptr<cairo_pattern> operator() (mapnik::marker_svg const& marker)
|
||||
{
|
||||
double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||
mapnik::rasterizer ras;
|
||||
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);
|
||||
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<image_rgba8>(ras, marker, image_tr, 1.0, image);
|
||||
width_ = image.width();
|
||||
height_ = image.height();
|
||||
return std::make_shared<cairo_pattern>(image, opacity);
|
||||
}
|
||||
|
||||
std::shared_ptr<cairo_pattern> operator() (mapnik::marker_rgba8 const& marker)
|
||||
{
|
||||
double opacity = get<value_double, keys::opacity>(sym_, feature_, common_.vars_);
|
||||
return std::make_shared<cairo_pattern>(marker.get_data(), opacity);
|
||||
}
|
||||
|
||||
private:
|
||||
renderer_common const& common_;
|
||||
line_pattern_symbolizer const& sym_;
|
||||
mapnik::feature_impl & feature_;
|
||||
unsigned & width_;
|
||||
unsigned & height_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
|
@ -48,39 +95,29 @@ void cairo_renderer<T>::process(line_pattern_symbolizer const& sym,
|
|||
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_);
|
||||
|
||||
boost::optional<marker_ptr> marker;
|
||||
if ( !filename.empty() )
|
||||
if (filename.empty())
|
||||
{
|
||||
marker = marker_cache::instance().find(filename, true);
|
||||
return;
|
||||
}
|
||||
if (!marker || !(*marker)) return;
|
||||
|
||||
unsigned width = (*marker)->width();
|
||||
unsigned height = (*marker)->height();
|
||||
mapnik::marker const& marker = marker_cache::instance().find(filename, true);
|
||||
|
||||
if (marker.is<mapnik::marker_null>()) return;
|
||||
|
||||
unsigned width = marker.width();
|
||||
unsigned height = marker.height();
|
||||
|
||||
cairo_save_restore guard(context_);
|
||||
context_.set_operator(comp_op);
|
||||
std::shared_ptr<cairo_pattern> pattern;
|
||||
image_ptr image = nullptr;
|
||||
// TODO - re-implement at renderer level like polygon_pattern symbolizer
|
||||
double opacity = get<value_double, keys::opacity>(sym, feature, common_.vars_);
|
||||
if ((*marker)->is_bitmap())
|
||||
{
|
||||
pattern = std::make_unique<cairo_pattern>(**((*marker)->get_bitmap_data()), opacity);
|
||||
context_.set_line_width(height);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapnik::rasterizer ras;
|
||||
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);
|
||||
image = render_pattern(ras, **marker, image_tr, 1.0);
|
||||
pattern = std::make_unique<cairo_pattern>(*image, opacity);
|
||||
width = image->width();
|
||||
height = image->height();
|
||||
context_.set_line_width(height);
|
||||
}
|
||||
cairo_renderer_process_visitor_l visit(common_,
|
||||
sym,
|
||||
feature,
|
||||
width,
|
||||
height);
|
||||
std::shared_ptr<cairo_pattern> pattern = util::apply_visitor(visit, marker);
|
||||
|
||||
context_.set_line_width(height);
|
||||
|
||||
pattern->set_extend(CAIRO_EXTEND_REPEAT);
|
||||
pattern->set_filter(CAIRO_FILTER_BILINEAR);
|
||||
|
|
|
@ -86,7 +86,7 @@ private:
|
|||
template <typename RendererContext, typename Detector>
|
||||
struct raster_markers_dispatch_cairo : public raster_markers_dispatch<Detector>
|
||||
{
|
||||
raster_markers_dispatch_cairo(mapnik::image_data_rgba8 & src,
|
||||
raster_markers_dispatch_cairo(image_rgba8 const& src,
|
||||
agg::trans_affine const& marker_trans,
|
||||
markers_symbolizer const& sym,
|
||||
Detector & detector,
|
||||
|
|
|
@ -37,6 +37,49 @@
|
|||
namespace mapnik
|
||||
{
|
||||
|
||||
struct cairo_renderer_process_visitor_p
|
||||
{
|
||||
cairo_renderer_process_visitor_p(cairo_context & context,
|
||||
agg::trans_affine & image_tr,
|
||||
unsigned offset_x,
|
||||
unsigned offset_y,
|
||||
float opacity)
|
||||
: context_(context),
|
||||
image_tr_(image_tr),
|
||||
offset_x_(offset_x),
|
||||
offset_y_(offset_y),
|
||||
opacity_(opacity) {}
|
||||
|
||||
void operator() (marker_null const&) {}
|
||||
|
||||
void operator() (marker_svg const& marker)
|
||||
{
|
||||
mapnik::rasterizer ras;
|
||||
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<image_rgba8>(ras, marker, image_tr_, 1.0, image);
|
||||
cairo_pattern pattern(image, opacity_);
|
||||
pattern.set_extend(CAIRO_EXTEND_REPEAT);
|
||||
pattern.set_origin(offset_x_, offset_y_);
|
||||
context_.set_pattern(pattern);
|
||||
}
|
||||
|
||||
void operator() (marker_rgba8 const& marker)
|
||||
{
|
||||
cairo_pattern pattern(marker.get_data(), opacity_);
|
||||
pattern.set_extend(CAIRO_EXTEND_REPEAT);
|
||||
pattern.set_origin(offset_x_, offset_y_);
|
||||
context_.set_pattern(pattern);
|
||||
}
|
||||
|
||||
private:
|
||||
cairo_context & context_;
|
||||
agg::trans_affine & image_tr_;
|
||||
unsigned offset_x_;
|
||||
unsigned offset_y_;
|
||||
float opacity_;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
|
||||
mapnik::feature_impl & feature,
|
||||
|
@ -55,8 +98,8 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
|
|||
cairo_save_restore guard(context_);
|
||||
context_.set_operator(comp_op);
|
||||
|
||||
boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true);
|
||||
if (!marker || !(*marker)) return;
|
||||
mapnik::marker const& marker = mapnik::marker_cache::instance().find(filename,true);
|
||||
if (marker.is<mapnik::marker_null>()) return;
|
||||
|
||||
unsigned offset_x=0;
|
||||
unsigned offset_y=0;
|
||||
|
@ -82,22 +125,7 @@ void cairo_renderer<T>::process(polygon_pattern_symbolizer const& sym,
|
|||
offset_y = std::abs(clip_box.height() - y0);
|
||||
}
|
||||
|
||||
if ((*marker)->is_bitmap())
|
||||
{
|
||||
cairo_pattern pattern(**((*marker)->get_bitmap_data()), opacity);
|
||||
pattern.set_extend(CAIRO_EXTEND_REPEAT);
|
||||
pattern.set_origin(offset_x, offset_y);
|
||||
context_.set_pattern(pattern);
|
||||
}
|
||||
else
|
||||
{
|
||||
mapnik::rasterizer ras;
|
||||
image_ptr image = render_pattern(ras, **marker, image_tr, 1.0); //
|
||||
cairo_pattern pattern(*image, opacity);
|
||||
pattern.set_extend(CAIRO_EXTEND_REPEAT);
|
||||
pattern.set_origin(offset_x, offset_y);
|
||||
context_.set_pattern(pattern);
|
||||
}
|
||||
util::apply_visitor(cairo_renderer_process_visitor_p(context_, image_tr, offset_x, offset_y, opacity), marker);
|
||||
|
||||
agg::trans_affine tr;
|
||||
auto geom_transform = get_optional<transform_type>(sym, keys::geometry_transform);
|
||||
|
|
|
@ -43,7 +43,7 @@ void cairo_renderer<T>::process(raster_symbolizer const& sym,
|
|||
cairo_save_restore guard(context_);
|
||||
render_raster_symbolizer(
|
||||
sym, feature, prj_trans, common_,
|
||||
[&](image_data_rgba8 &target, composite_mode_e comp_op, double opacity,
|
||||
[&](image_rgba8 &target, composite_mode_e comp_op, double opacity,
|
||||
int start_x, int start_y) {
|
||||
context_.set_operator(comp_op);
|
||||
context_.add_image(start_x, start_y, target, opacity);
|
||||
|
|
|
@ -60,7 +60,7 @@ void cairo_renderer<T>::process(shield_symbolizer const& sym,
|
|||
if (glyphs->marker()) {
|
||||
pixel_position pos = glyphs->marker_pos();
|
||||
render_marker(pos,
|
||||
*(glyphs->marker()->marker),
|
||||
glyphs->marker()->marker,
|
||||
glyphs->marker()->transform,
|
||||
opacity);
|
||||
}
|
||||
|
|
131
src/cairo_io.cpp
Normal file
131
src/cairo_io.cpp
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/cairo_io.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/map.hpp>
|
||||
|
||||
#ifdef HAVE_CAIRO
|
||||
#include <mapnik/cairo/cairo_renderer.hpp>
|
||||
#include <cairo.h>
|
||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||
#include <cairo-pdf.h>
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_PS_SURFACE
|
||||
#include <cairo-ps.h>
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
#include <cairo-svg.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// stl
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
namespace mapnik {
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
void save_to_cairo_file(mapnik::Map const& map, std::string const& filename, double scale_factor, double scale_denominator)
|
||||
{
|
||||
boost::optional<std::string> type = type_from_filename(filename);
|
||||
if (type)
|
||||
{
|
||||
save_to_cairo_file(map,filename,*type,scale_factor,scale_denominator);
|
||||
}
|
||||
else throw ImageWriterException("Could not write file to " + filename );
|
||||
}
|
||||
|
||||
void save_to_cairo_file(mapnik::Map const& map,
|
||||
std::string const& filename,
|
||||
std::string const& type,
|
||||
double scale_factor,
|
||||
double scale_denominator)
|
||||
{
|
||||
std::ofstream file (filename.c_str(), std::ios::out|std::ios::trunc|std::ios::binary);
|
||||
if (file)
|
||||
{
|
||||
cairo_surface_ptr surface;
|
||||
unsigned width = map.width();
|
||||
unsigned height = map.height();
|
||||
if (type == "pdf")
|
||||
{
|
||||
#ifdef CAIRO_HAS_PDF_SURFACE
|
||||
surface = cairo_surface_ptr(cairo_pdf_surface_create(filename.c_str(),width,height),cairo_surface_closer());
|
||||
#else
|
||||
throw ImageWriterException("PDFSurface not supported in the cairo backend");
|
||||
#endif
|
||||
}
|
||||
#ifdef CAIRO_HAS_SVG_SURFACE
|
||||
else if (type == "svg")
|
||||
{
|
||||
surface = cairo_surface_ptr(cairo_svg_surface_create(filename.c_str(),width,height),cairo_surface_closer());
|
||||
}
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_PS_SURFACE
|
||||
else if (type == "ps")
|
||||
{
|
||||
surface = cairo_surface_ptr(cairo_ps_surface_create(filename.c_str(),width,height),cairo_surface_closer());
|
||||
}
|
||||
#endif
|
||||
#ifdef CAIRO_HAS_IMAGE_SURFACE
|
||||
else if (type == "ARGB32")
|
||||
{
|
||||
surface = cairo_surface_ptr(cairo_image_surface_create(CAIRO_FORMAT_ARGB32,width,height),cairo_surface_closer());
|
||||
}
|
||||
else if (type == "RGB24")
|
||||
{
|
||||
surface = cairo_surface_ptr(cairo_image_surface_create(CAIRO_FORMAT_RGB24,width,height),cairo_surface_closer());
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
throw ImageWriterException("unknown file type: " + type);
|
||||
}
|
||||
|
||||
//cairo_t * ctx = cairo_create(surface);
|
||||
|
||||
// TODO - expose as user option
|
||||
/*
|
||||
if (type == "ARGB32" || type == "RGB24")
|
||||
{
|
||||
context->set_antialias(Cairo::ANTIALIAS_NONE);
|
||||
}
|
||||
*/
|
||||
|
||||
mapnik::cairo_renderer<cairo_ptr> ren(map, create_context(surface), scale_factor);
|
||||
ren.apply(scale_denominator);
|
||||
|
||||
if (type == "ARGB32" || type == "RGB24")
|
||||
{
|
||||
cairo_surface_write_to_png(&*surface, filename.c_str());
|
||||
}
|
||||
cairo_surface_finish(&*surface);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // end ns
|
|
@ -45,9 +45,10 @@
|
|||
|
||||
namespace mapnik {
|
||||
|
||||
color::color(std::string const& str)
|
||||
color::color(std::string const& str, bool premultiplied)
|
||||
{
|
||||
*this = parse_color(str);
|
||||
premultiplied_ = premultiplied;
|
||||
}
|
||||
|
||||
std::string color::to_string() const
|
||||
|
@ -95,23 +96,28 @@ std::string color::to_hex_string() const
|
|||
return str;
|
||||
}
|
||||
|
||||
void color::premultiply()
|
||||
bool color::premultiply()
|
||||
{
|
||||
if (premultiplied_) return false;
|
||||
agg::rgba8 pre_c = agg::rgba8(red_,green_,blue_,alpha_);
|
||||
pre_c.premultiply();
|
||||
red_ = pre_c.r;
|
||||
green_ = pre_c.g;
|
||||
blue_ = pre_c.b;
|
||||
premultiplied_ = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
void color::demultiply()
|
||||
bool color::demultiply()
|
||||
{
|
||||
// note: this darkens too much: https://github.com/mapnik/mapnik/issues/1519
|
||||
if (!premultiplied_) return false;
|
||||
agg::rgba8 pre_c = agg::rgba8(red_,green_,blue_,alpha_);
|
||||
pre_c.demultiply();
|
||||
red_ = pre_c.r;
|
||||
green_ = pre_c.g;
|
||||
blue_ = pre_c.b;
|
||||
premultiplied_ = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
#include <mapnik/feature_style_processor_impl.hpp>
|
||||
#include <mapnik/agg_renderer.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_any.hpp>
|
||||
|
||||
#if defined(GRID_RENDERER)
|
||||
#include <mapnik/grid/grid_renderer.hpp>
|
||||
|
@ -44,17 +44,17 @@ namespace mapnik
|
|||
{
|
||||
|
||||
#if defined(HAVE_CAIRO)
|
||||
template class feature_style_processor<cairo_renderer<cairo_ptr> >;
|
||||
template class MAPNIK_DECL feature_style_processor<cairo_renderer<cairo_ptr> >;
|
||||
#endif
|
||||
|
||||
#if defined(SVG_RENDERER)
|
||||
template class feature_style_processor<svg_renderer<std::ostream_iterator<char> > >;
|
||||
template class MAPNIK_DECL feature_style_processor<svg_renderer<std::ostream_iterator<char> > >;
|
||||
#endif
|
||||
|
||||
#if defined(GRID_RENDERER)
|
||||
template class feature_style_processor<grid_renderer<grid> >;
|
||||
template class MAPNIK_DECL feature_style_processor<grid_renderer<grid> >;
|
||||
#endif
|
||||
|
||||
template class feature_style_processor<agg_renderer<image_32> >;
|
||||
template class MAPNIK_DECL feature_style_processor<agg_renderer<image_rgba8> >;
|
||||
|
||||
}
|
||||
|
|
166
src/graphics.cpp
166
src/graphics.cpp
|
@ -1,166 +0,0 @@
|
|||
/*****************************************************************************
|
||||
*
|
||||
* This file is part of Mapnik (c++ mapping toolkit)
|
||||
*
|
||||
* Copyright (C) 2014 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
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
// mapnik
|
||||
#include <mapnik/debug.hpp>
|
||||
#include <mapnik/graphics.hpp>
|
||||
#include <mapnik/image_util.hpp>
|
||||
#include <mapnik/global.hpp>
|
||||
#include <mapnik/color.hpp>
|
||||
|
||||
// agg
|
||||
#include "agg_rendering_buffer.h"
|
||||
#include "agg_pixfmt_rgba.h"
|
||||
#include "agg_color_rgba.h"
|
||||
|
||||
#ifdef HAVE_CAIRO
|
||||
#include <mapnik/cairo/cairo_context.hpp>
|
||||
#endif
|
||||
|
||||
namespace mapnik
|
||||
{
|
||||
image_32::image_32(int width,int height)
|
||||
: data_(width,height),
|
||||
painted_(false),
|
||||
premultiplied_(false) {}
|
||||
|
||||
|
||||
image_32::image_32(image_32 const& rhs)
|
||||
: data_(rhs.data_),
|
||||
painted_(rhs.painted_),
|
||||
premultiplied_(rhs.premultiplied_) {}
|
||||
|
||||
image_32::image_32(image_data_rgba8 && data)
|
||||
: data_(std::move(data)),
|
||||
painted_(false),
|
||||
premultiplied_(false) {}
|
||||
|
||||
image_32::~image_32() {}
|
||||
|
||||
void image_32::set_grayscale_to_alpha()
|
||||
{
|
||||
for (unsigned int y = 0; y < data_.height(); ++y)
|
||||
{
|
||||
unsigned int* row_from = data_.getRow(y);
|
||||
for (unsigned int x = 0; x < data_.width(); ++x)
|
||||
{
|
||||
unsigned rgba = row_from[x];
|
||||
unsigned r = rgba & 0xff;
|
||||
unsigned g = (rgba >> 8 ) & 0xff;
|
||||
unsigned b = (rgba >> 16) & 0xff;
|
||||
|
||||
// magic numbers for grayscale
|
||||
unsigned a = static_cast<unsigned>(std::ceil((r * .3) + (g * .59) + (b * .11)));
|
||||
|
||||
row_from[x] = (a << 24)| (255 << 16) | (255 << 8) | (255) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image_32::set_color_to_alpha(const color& c)
|
||||
{
|
||||
for (unsigned y = 0; y < data_.height(); ++y)
|
||||
{
|
||||
unsigned int* row_from = data_.getRow(y);
|
||||
for (unsigned x = 0; x < data_.width(); ++x)
|
||||
{
|
||||
unsigned rgba = row_from[x];
|
||||
unsigned r = rgba & 0xff;
|
||||
unsigned g = (rgba >> 8 ) & 0xff;
|
||||
unsigned b = (rgba >> 16) & 0xff;
|
||||
if (r == c.red() && g == c.green() && b == c.blue())
|
||||
{
|
||||
row_from[x] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image_32::set_alpha(float opacity)
|
||||
{
|
||||
for (unsigned int y = 0; y < data_.height(); ++y)
|
||||
{
|
||||
unsigned int* row_to = data_.getRow(y);
|
||||
for (unsigned int x = 0; x < data_.width(); ++x)
|
||||
{
|
||||
unsigned rgba = row_to[x];
|
||||
unsigned a0 = (rgba >> 24) & 0xff;
|
||||
unsigned a1 = int( ((rgba >> 24) & 0xff) * opacity );
|
||||
//unsigned a1 = opacity;
|
||||
if (a0 == a1) continue;
|
||||
|
||||
unsigned r = rgba & 0xff;
|
||||
unsigned g = (rgba >> 8 ) & 0xff;
|
||||
unsigned b = (rgba >> 16) & 0xff;
|
||||
|
||||
row_to[x] = (a1 << 24)| (b << 16) | (g << 8) | (r) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void image_32::set_background(const color& c)
|
||||
{
|
||||
background_=c;
|
||||
data_.set(background_->rgba());
|
||||
}
|
||||
|
||||
boost::optional<color> const& image_32::get_background() const
|
||||
{
|
||||
return background_;
|
||||
}
|
||||
|
||||
void image_32::premultiply()
|
||||
{
|
||||
agg::rendering_buffer buffer(data_.getBytes(),data_.width(),data_.height(),data_.width() * 4);
|
||||
agg::pixfmt_rgba32 pixf(buffer);
|
||||
pixf.premultiply();
|
||||
premultiplied_ = true;
|
||||
}
|
||||
|
||||
void image_32::demultiply()
|
||||
{
|
||||
agg::rendering_buffer buffer(data_.getBytes(),data_.width(),data_.height(),data_.width() * 4);
|
||||
agg::pixfmt_rgba32_pre pixf(buffer);
|
||||
pixf.demultiply();
|
||||
premultiplied_ = false;
|
||||
}
|
||||
|
||||
void image_32::composite_pixel(unsigned op, int x,int y, unsigned c, unsigned cover, double opacity)
|
||||
{
|
||||
using color_type = agg::rgba8;
|
||||
using value_type = color_type::value_type;
|
||||
using order_type = agg::order_rgba;
|
||||
using blender_type = agg::comp_op_adaptor_rgba<color_type,order_type>;
|
||||
|
||||
if (checkBounds(x,y))
|
||||
{
|
||||
unsigned rgba = data_(x,y);
|
||||
unsigned ca = (unsigned)(((c >> 24) & 0xff) * opacity);
|
||||
unsigned cb = (c >> 16 ) & 0xff;
|
||||
unsigned cg = (c >> 8) & 0xff;
|
||||
unsigned cr = (c & 0xff);
|
||||
blender_type::blend_pix(op, (value_type*)&rgba, cr, cg, cb, ca, cover);
|
||||
data_(x,y) = rgba;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -34,7 +34,7 @@ namespace mapnik
|
|||
{
|
||||
|
||||
template <typename T>
|
||||
const typename hit_grid<T>::value_type hit_grid<T>::base_mask = std::numeric_limits<T>::min();
|
||||
const typename hit_grid<T>::value_type hit_grid<T>::base_mask = std::numeric_limits<typename T::type>::min();
|
||||
|
||||
template <typename T>
|
||||
hit_grid<T>::hit_grid(int width, int height, std::string const& key, unsigned int resolution)
|
||||
|
@ -146,7 +146,7 @@ void hit_grid<T>::add_feature(mapnik::feature_impl const& feature)
|
|||
}
|
||||
|
||||
|
||||
template class hit_grid<mapnik::value_integer>;
|
||||
template class MAPNIK_DECL hit_grid<mapnik::value_integer_pixel>;
|
||||
|
||||
}
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue