support image-transform for vector patterns

This commit is contained in:
artemp 2014-08-01 13:39:29 +01:00
parent a9f0408e4f
commit f2db42d5e4
5 changed files with 27 additions and 12 deletions

View file

@ -182,7 +182,7 @@ private:
void setup(Map const& m); void setup(Map const& m);
}; };
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker); std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker, agg::trans_affine const& tr);
} // namespace mapnik } // namespace mapnik

View file

@ -502,22 +502,27 @@ void agg_renderer<T0,T1>::draw_geo_extent(box2d<double> const& extent, mapnik::c
} }
} }
std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker) std::shared_ptr<image_data_32> render_pattern(rasterizer & ras, marker const& marker, agg::trans_affine const& tr)
{ {
using pixfmt = agg::pixfmt_rgba32_pre; using pixfmt = agg::pixfmt_rgba32_pre;
using renderer_base = agg::renderer_base<pixfmt>; using renderer_base = agg::renderer_base<pixfmt>;
using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>; using renderer_solid = agg::renderer_scanline_aa_solid<renderer_base>;
agg::scanline_u8 sl; agg::scanline_u8 sl;
double width = marker.width();
double height = marker.height(); //double width = marker.width();
std::shared_ptr<mapnik::image_data_32> image = std::make_shared<mapnik::image_data_32>(width, height); //double height = marker.height();
mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box() * tr;
mapnik::coord<double,2> c = bbox.center();
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
mtx.translate(0.5 * bbox.width(), 0.5 * bbox.height());
mtx = tr * mtx;
std::shared_ptr<mapnik::image_data_32> image = std::make_shared<mapnik::image_data_32>(bbox.width(), bbox.height());
agg::rendering_buffer buf(image->getBytes(), image->width(), image->height(), image->width() * 4); agg::rendering_buffer buf(image->getBytes(), image->width(), image->height(), image->width() * 4);
pixfmt pixf(buf); pixfmt pixf(buf);
renderer_base renb(pixf); renderer_base renb(pixf);
mapnik::box2d<double> const& bbox = (*marker.get_vector_data())->bounding_box();
mapnik::coord<double,2> c = bbox.center();
agg::trans_affine mtx = agg::trans_affine_translation(-c.x,-c.y);
mtx.translate(0.5 * image->width(), 0.5 * image->height());
mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source()); mapnik::svg::vertex_stl_adapter<mapnik::svg::svg_path_storage> stl_storage((*marker.get_vector_data())->source());
mapnik::svg::svg_path_adapter svg_path(stl_storage); mapnik::svg::svg_path_adapter svg_path(stl_storage);
mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter, mapnik::svg::svg_renderer_agg<mapnik::svg::svg_path_adapter,

View file

@ -111,7 +111,10 @@ void agg_renderer<T0,T1>::process(line_pattern_symbolizer const& sym,
} }
else else
{ {
pat = render_pattern(*ras_ptr, **marker_ptr); 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);
} }
if (!pat) return; if (!pat) return;

View file

@ -70,7 +70,10 @@ void agg_renderer<T0,T1>::process(polygon_pattern_symbolizer const& sym,
} }
else else
{ {
pat = render_pattern(*ras_ptr, **marker_ptr); 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);
} }
if (!pat) return; if (!pat) return;

View file

@ -691,6 +691,10 @@ void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0); double simplify_tolerance = get<double>(sym, keys::simplify_tolerance, feature, common_.vars_, 0.0);
double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0); double smooth = get<double>(sym, keys::smooth, feature, common_.vars_, 0.0);
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);
context_.set_operator(comp_op); context_.set_operator(comp_op);
boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true); boost::optional<mapnik::marker_ptr> marker = mapnik::marker_cache::instance().find(filename,true);
@ -705,7 +709,7 @@ void cairo_renderer_base::process(polygon_pattern_symbolizer const& sym,
else else
{ {
mapnik::rasterizer ras; mapnik::rasterizer ras;
image_ptr image = render_pattern(ras, **marker); image_ptr image = render_pattern(ras, **marker, image_tr);
cairo_pattern pattern(*image); cairo_pattern pattern(*image);
pattern.set_extend(CAIRO_EXTEND_REPEAT); pattern.set_extend(CAIRO_EXTEND_REPEAT);
context_.set_pattern(pattern); context_.set_pattern(pattern);