Add ability to scale SVGs by specifying different image dimensions.
This commit is contained in:
parent
776436db6e
commit
f6a858b6c9
2 changed files with 33 additions and 10 deletions
|
@ -178,7 +178,7 @@ boost::optional<box2d<double> > svg_reader<T>::bounding_box() const
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
void svg_reader<T>::read(unsigned x0, unsigned y0,image_rgba8& image)
|
||||
void svg_reader<T>::read(unsigned x0, unsigned y0, image_rgba8& image)
|
||||
{
|
||||
using pixfmt = agg::pixfmt_rgba32_pre;
|
||||
using renderer_base = agg::renderer_base<pixfmt>;
|
||||
|
@ -187,12 +187,11 @@ void svg_reader<T>::read(unsigned x0, unsigned y0,image_rgba8& image)
|
|||
agg::scanline_u8 sl;
|
||||
|
||||
double opacity = 1;
|
||||
int w = width_;
|
||||
int h = height_;
|
||||
unsigned w = std::min(unsigned(image.width()),width_ - x0);
|
||||
unsigned h = std::min(unsigned(image.height()),height_ - y0);
|
||||
|
||||
// 10 pixel buffer to avoid edge clipping of 100% svg's
|
||||
mapnik::image_rgba8 im(w+0,h+0);
|
||||
agg::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
|
||||
agg::rendering_buffer buf(image.bytes(), image.width(), image.height(), image.row_size());
|
||||
pixfmt pixf(buf);
|
||||
renderer_base renb(pixf);
|
||||
|
||||
|
@ -200,8 +199,10 @@ void svg_reader<T>::read(unsigned x0, unsigned y0,image_rgba8& image)
|
|||
mapnik::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);
|
||||
// Scale if necessary
|
||||
mtx.scale((double)w / width_, (double)h / height_);
|
||||
// render the marker at the center of the marker box
|
||||
mtx.translate(0.5 * im.width(), 0.5 * im.height());
|
||||
mtx.translate(0.5 * image.width(), 0.5 * image.height());
|
||||
|
||||
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage(marker->get_data()->source());
|
||||
mapnik::svg::svg_path_adapter svg_path(stl_storage);
|
||||
|
@ -213,9 +214,7 @@ void svg_reader<T>::read(unsigned x0, unsigned y0,image_rgba8& image)
|
|||
|
||||
svg_renderer_this.render(ras_ptr, sl, renb, mtx, opacity, bbox);
|
||||
|
||||
demultiply_alpha(im);
|
||||
|
||||
image = im;
|
||||
demultiply_alpha(image);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ SECTION("svg_empty")
|
|||
CHECK(height == 0);
|
||||
}
|
||||
|
||||
SECTION("svg_blank")
|
||||
SECTION("svg_simple")
|
||||
{
|
||||
std::string imagedata = "<svg width='100' height='100'><g id='a'><ellipse fill='#FFFFFF' stroke='#000000' stroke-width='4' cx='50' cy='50' rx='25' ry='25'/></g></svg>";
|
||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(imagedata.c_str(), imagedata.length()));
|
||||
|
@ -62,5 +62,29 @@ SECTION("svg_blank")
|
|||
|
||||
} // END SECTION
|
||||
|
||||
SECTION("svg_scaled")
|
||||
{
|
||||
std::string imagedata = "<svg width='100' height='100'><g id='a'><ellipse fill='#FFFFFF' stroke='#000000' stroke-width='4' cx='50' cy='50' rx='25' ry='25'/></g></svg>";
|
||||
std::unique_ptr<mapnik::image_reader> reader(mapnik::get_image_reader(imagedata.c_str(), imagedata.length()));
|
||||
CHECK(reader.get());
|
||||
unsigned width = reader->width();
|
||||
unsigned height = reader->height();
|
||||
|
||||
CHECK(width == 100);
|
||||
CHECK(height == 100);
|
||||
|
||||
mapnik::image_any im = reader->read(0,0,width/2,height/2);
|
||||
|
||||
mapnik::image_rgba8 raw = im.get<mapnik::image_rgba8>();
|
||||
|
||||
CHECK(im.width() == 50);
|
||||
CHECK(im.height() == 50);
|
||||
|
||||
std::string pngdata = mapnik::save_to_string<mapnik::image_rgba8>(raw,"png");
|
||||
mapnik::save_to_file<mapnik::image_rgba8>(raw,"test.png","png");
|
||||
CHECK(pngdata.length() == 1270);
|
||||
|
||||
} // END SECTION
|
||||
|
||||
} // END TEST CASE
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue