+ support compositing across all symbolizers

(currently polygon and line symbolizers)
This commit is contained in:
Artem Pavlenko 2012-04-05 15:59:11 +01:00
parent 0618f9ca42
commit 34c984b2b8
8 changed files with 120 additions and 61 deletions

View file

@ -28,7 +28,6 @@
#include <mapnik/symbolizer.hpp>
#include <mapnik/enumeration.hpp>
#include <mapnik/gamma_method.hpp>
#include <mapnik/image_compositing.hpp>
namespace mapnik
{
@ -47,15 +46,12 @@ struct MAPNIK_DECL compositing_symbolizer : public symbolizer_base
gamma_method_e get_gamma_method() const;
void set_smooth(double smooth);
double smooth() const;
void set_comp_op(composite_mode_e comp_op);
composite_mode_e comp_op() const;
private:
color fill_;
double opacity_;
double gamma_;
gamma_method_e gamma_method_;
double smooth_;
composite_mode_e comp_op_;
};
}

View file

@ -27,6 +27,7 @@
#include <mapnik/config.hpp>
#include <mapnik/parse_path.hpp>
#include <mapnik/metawriter.hpp>
#include <mapnik/image_compositing.hpp>
// boost
#include <boost/array.hpp>
@ -42,8 +43,9 @@ public:
properties_(),
properties_complete_(),
writer_name_(),
writer_ptr_() {}
writer_ptr_(),
comp_op_(clear) {}
/** Add a metawriter to this symbolizer using a name. */
void add_metawriter(std::string const& name, metawriter_properties const& properties);
/** Add a metawriter to this symbolizer using a pointer.
@ -77,11 +79,15 @@ public:
metawriter_properties const& get_metawriter_properties_overrides() const { return properties_; }
/** Get metawriter name. */
std::string const& get_metawriter_name() const { return writer_name_; }
void set_comp_op(composite_mode_e comp_op);
composite_mode_e comp_op() const;
private:
metawriter_properties properties_;
metawriter_properties properties_complete_;
std::string writer_name_;
metawriter_ptr writer_ptr_;
composite_mode_e comp_op_;
};
typedef boost::array<double,6> transform_type;

View file

@ -52,23 +52,18 @@ void agg_renderer<T>::process(compositing_symbolizer const& sym,
typedef agg::order_rgba order_type;
typedef agg::pixel32_type pixel_type;
typedef agg::comp_op_adaptor_rgba<color_type, order_type> blender_type; // comp blender
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
typedef agg::renderer_base<pixfmt_type> renderer_base;
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
color const& fill_ = sym.get_fill();
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
pixfmt_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf);
unsigned r=fill_.red();
unsigned g=fill_.green();
unsigned b=fill_.blue();
unsigned a=fill_.alpha();
renderer_type ren(renb);
ras_ptr->reset();
@ -105,9 +100,28 @@ void agg_renderer<T>::process(compositing_symbolizer const& sym,
}
}
}
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
agg::scanline_u8 sl;
agg::render_scanlines(*ras_ptr, sl, ren);
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
if (sym.comp_op() == clear)
{
aa_renderer::pixfmt_type pixf(buf);
aa_renderer ren;
ren.attach(pixf);
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
ren.render(*ras_ptr);
}
else
{
pixfmt_comp_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf);
renderer_type ren(renb);
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
agg::scanline_u8 sl;
agg::render_scanlines(*ras_ptr, sl, ren);
}
}

View file

@ -125,8 +125,34 @@ void agg_renderer<T>::process(line_symbolizer const& sym,
}
}
ren.color(agg::rgba8(r, g, b, int(a*stroke_.get_opacity())));
ren.render(*ras_ptr);
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
if (sym.comp_op() == clear)
{
aa_renderer::pixfmt_type pixf(buf);
aa_renderer ren;
ren.attach(pixf);
ren.color(agg::rgba8(r, g, b, int(a * stroke_.get_opacity())));
ren.render(*ras_ptr);
}
else
{
typedef agg::rgba8 color_type;
typedef agg::order_rgba order_type;
typedef agg::pixel32_type pixel_type;
typedef agg::comp_op_adaptor_rgba<color_type, order_type> blender_type; // comp blender
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
pixfmt_comp_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf);
renderer_type ren(renb);
ren.color(agg::rgba8(r, g, b, int(a * stroke_.get_opacity())));
agg::scanline_u8 sl;
agg::render_scanlines(*ras_ptr, sl, ren);
}
}
}

View file

@ -42,14 +42,10 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
mapnik::feature_ptr const& feature,
proj_transform const& prj_trans)
{
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
aa_renderer::pixel_format_type pixf(buf);
ras_ptr->reset();
set_gamma_method(sym,ras_ptr);
aa_renderer ren;
ren.attach(pixf);
box2d<double> inflated_extent = query_extent_ * 1.1;
typedef boost::mpl::vector<clip_poly_tag,transform_tag,smooth_tag> conv_types;
@ -64,27 +60,44 @@ void agg_renderer<T>::process(polygon_symbolizer const& sym,
{
geometry_type & geom=feature->get_geometry(i);
if (geom.num_points() > 2)
{
//typedef agg::conv_clip_polygon<geometry_type> clipped_geometry_type;
//typedef coord_transform2<CoordTransform,clipped_geometry_type> path_type;
//clipped_geometry_type clipped(geom);
//clipped.clip_box(inflated_extent.minx(),inflated_extent.miny(),inflated_extent.maxx(),inflated_extent.maxy());
//path_type path(t_,clipped,prj_trans);
{
converter.apply(geom);
}
}
color const& fill_ = sym.get_fill();
unsigned r=fill_.red();
unsigned g=fill_.green();
unsigned b=fill_.blue();
unsigned a=fill_.alpha();
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
ren.render(*ras_ptr);
agg::rendering_buffer buf(current_buffer_->raw_data(),width_,height_, width_ * 4);
color const& fill = sym.get_fill();
unsigned r=fill.red();
unsigned g=fill.green();
unsigned b=fill.blue();
unsigned a=fill.alpha();
if (sym.comp_op() == clear)
{
aa_renderer::pixfmt_type pixf(buf);
aa_renderer ren;
ren.attach(pixf);
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
ren.render(*ras_ptr);
}
else
{
typedef agg::rgba8 color_type;
typedef agg::order_rgba order_type;
typedef agg::pixel32_type pixel_type;
typedef agg::comp_op_adaptor_rgba<color_type, order_type> blender_type; // comp blender
typedef agg::pixfmt_custom_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_comp_type;
typedef agg::renderer_base<pixfmt_comp_type> renderer_base;
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_type;
pixfmt_comp_type pixf(buf);
pixf.comp_op(static_cast<agg::comp_op_e>(sym.comp_op()));
renderer_base renb(pixf);
renderer_type ren(renb);
ren.color(agg::rgba8(r, g, b, int(a * sym.get_opacity())));
agg::scanline_u8 sl;
agg::render_scanlines(*ras_ptr, sl, ren);
}
}

View file

@ -33,8 +33,7 @@ compositing_symbolizer::compositing_symbolizer()
opacity_(1.0),
gamma_(1.0),
gamma_method_(GAMMA_POWER),
smooth_(0.0),
comp_op_(clear) {}
smooth_(0.0) {}
compositing_symbolizer::compositing_symbolizer(color const& fill)
: symbolizer_base(),
@ -42,8 +41,7 @@ compositing_symbolizer::compositing_symbolizer(color const& fill)
opacity_(1.0),
gamma_(1.0),
gamma_method_(GAMMA_POWER),
smooth_(0.0),
comp_op_(clear) {}
smooth_(0.0) {}
color const& compositing_symbolizer::get_fill() const
{
@ -95,14 +93,4 @@ double compositing_symbolizer::smooth() const
return smooth_;
}
void compositing_symbolizer::set_comp_op(composite_mode_e comp_op)
{
comp_op_ = comp_op;
}
composite_mode_e compositing_symbolizer::comp_op() const
{
return comp_op_;
}
}

View file

@ -762,10 +762,20 @@ void map_parser::parse_rule(feature_type_style & style, xml_node const& r)
void map_parser::parse_metawriter_in_symbolizer(symbolizer_base &sym, xml_node const &pt)
{
optional<std::string> comp_op_name = pt.get_opt_attr<std::string>("comp-op");
if (comp_op_name)
{
composite_mode_e comp_op = comp_op_from_string(*comp_op_name);
sym.set_comp_op(comp_op);
}
optional<std::string> writer = pt.get_opt_attr<std::string>("meta-writer");
if (!writer) return;
optional<std::string> output = pt.get_opt_attr<std::string>("meta-output");
sym.add_metawriter(*writer, output);
}
void map_parser::parse_point_symbolizer(rule & rule, xml_node const & sym)
@ -1360,12 +1370,6 @@ void map_parser::parse_compositing_symbolizer(rule & rule, xml_node const & sym)
optional<double> smooth = sym.get_opt_attr<double>("smooth");
if (smooth) comp_sym.set_smooth(*smooth);
optional<std::string> comp_op_name = sym.get_opt_attr<std::string>("comp-op");
if (comp_op_name)
{
composite_mode_e comp_op = comp_op_from_string(*comp_op_name);
comp_sym.set_comp_op(comp_op);
}
rule.append(comp_sym);
}
catch (const config_error & ex)

View file

@ -65,11 +65,23 @@ void symbolizer_base::cache_metawriters(Map const &m)
}
}
metawriter_with_properties symbolizer_base::get_metawriter() const
{
return metawriter_with_properties(writer_ptr_, properties_complete_);
}
void symbolizer_base::set_comp_op(composite_mode_e comp_op)
{
comp_op_ = comp_op;
}
composite_mode_e symbolizer_base::comp_op() const
{
return comp_op_;
}
symbolizer_with_image::symbolizer_with_image(path_expression_ptr file)
: image_filename_( file ),
image_opacity_(1.0f)