+ 'direct' image filter support: apply filter on main rendering buffer
(TODO: better user-friendly names) + allow empty string e.g image-filters="" (why not?)
This commit is contained in:
parent
c26ad5706e
commit
f57d2c28f0
4 changed files with 58 additions and 11 deletions
|
@ -55,6 +55,7 @@ private:
|
||||||
filter_mode_e filter_mode_;
|
filter_mode_e filter_mode_;
|
||||||
// image_filters
|
// image_filters
|
||||||
std::vector<filter::filter_type> filters_;
|
std::vector<filter::filter_type> filters_;
|
||||||
|
std::vector<filter::filter_type> direct_filters_;
|
||||||
// comp-op
|
// comp-op
|
||||||
boost::optional<composite_mode_e> comp_op_;
|
boost::optional<composite_mode_e> comp_op_;
|
||||||
// The rule_ptrs vectors are only valid for the scale_denom_validity_.
|
// The rule_ptrs vectors are only valid for the scale_denom_validity_.
|
||||||
|
@ -76,14 +77,16 @@ public:
|
||||||
rule_ptrs const& get_else_rules(double scale_denom);
|
rule_ptrs const& get_else_rules(double scale_denom);
|
||||||
rule_ptrs const& get_also_rules(double scale_denom);
|
rule_ptrs const& get_also_rules(double scale_denom);
|
||||||
|
|
||||||
rules &get_rules_nonconst();
|
rules& get_rules_nonconst();
|
||||||
|
|
||||||
void set_filter_mode(filter_mode_e mode);
|
void set_filter_mode(filter_mode_e mode);
|
||||||
|
|
||||||
filter_mode_e get_filter_mode() const;
|
filter_mode_e get_filter_mode() const;
|
||||||
// filters
|
// filters
|
||||||
std::vector<filter::filter_type> const& image_filters() const;
|
std::vector<filter::filter_type> const& image_filters() const;
|
||||||
std::vector<filter::filter_type> & image_filters();
|
std::vector<filter::filter_type> & image_filters();
|
||||||
|
std::vector<filter::filter_type> const& direct_image_filters() const;
|
||||||
|
std::vector<filter::filter_type> & direct_image_filters();
|
||||||
// compositing
|
// compositing
|
||||||
void set_comp_op(composite_mode_e comp_op);
|
void set_comp_op(composite_mode_e comp_op);
|
||||||
boost::optional<composite_mode_e> comp_op() const;
|
boost::optional<composite_mode_e> comp_op() const;
|
||||||
|
|
|
@ -252,6 +252,14 @@ void agg_renderer<T>::end_style_processing(feature_type_style const& st)
|
||||||
{
|
{
|
||||||
composite(pixmap_.data(),current_buffer_->data(), src_over,false,false);
|
composite(pixmap_.data(),current_buffer_->data(), src_over,false,false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// apply any 'direct' image filters
|
||||||
|
mapnik::filter::filter_visitor<image_32> visitor(pixmap_);
|
||||||
|
BOOST_FOREACH(mapnik::filter::filter_type filter_tag, st.direct_image_filters())
|
||||||
|
{
|
||||||
|
boost::apply_visitor(visitor, filter_tag);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MAPNIK_DEBUG
|
#ifdef MAPNIK_DEBUG
|
||||||
std::clog << "end style processing\n";
|
std::clog << "end style processing\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -37,12 +37,14 @@ IMPLEMENT_ENUM( filter_mode_e, filter_mode_strings )
|
||||||
feature_type_style::feature_type_style()
|
feature_type_style::feature_type_style()
|
||||||
: filter_mode_(FILTER_ALL),
|
: filter_mode_(FILTER_ALL),
|
||||||
filters_(),
|
filters_(),
|
||||||
|
direct_filters_(),
|
||||||
scale_denom_validity_(-1)
|
scale_denom_validity_(-1)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
feature_type_style::feature_type_style(feature_type_style const& rhs, bool deep_copy)
|
feature_type_style::feature_type_style(feature_type_style const& rhs, bool deep_copy)
|
||||||
: filter_mode_(rhs.filter_mode_),
|
: filter_mode_(rhs.filter_mode_),
|
||||||
filters_(rhs.filters_),
|
filters_(rhs.filters_),
|
||||||
|
direct_filters_(rhs.direct_filters_),
|
||||||
comp_op_(rhs.comp_op_),
|
comp_op_(rhs.comp_op_),
|
||||||
scale_denom_validity_(-1)
|
scale_denom_validity_(-1)
|
||||||
{
|
{
|
||||||
|
@ -62,6 +64,7 @@ feature_type_style& feature_type_style::operator=(feature_type_style const& rhs)
|
||||||
if (this == &rhs) return *this;
|
if (this == &rhs) return *this;
|
||||||
rules_=rhs.rules_;
|
rules_=rhs.rules_;
|
||||||
filters_ = rhs.filters_;
|
filters_ = rhs.filters_;
|
||||||
|
direct_filters_ = rhs.direct_filters_;
|
||||||
comp_op_ = rhs.comp_op_;
|
comp_op_ = rhs.comp_op_;
|
||||||
scale_denom_validity_ = -1;
|
scale_denom_validity_ = -1;
|
||||||
return *this;
|
return *this;
|
||||||
|
@ -78,7 +81,7 @@ rules const& feature_type_style::get_rules() const
|
||||||
return rules_;
|
return rules_;
|
||||||
}
|
}
|
||||||
|
|
||||||
rules &feature_type_style::get_rules_nonconst()
|
rules& feature_type_style::get_rules_nonconst()
|
||||||
{
|
{
|
||||||
return rules_;
|
return rules_;
|
||||||
}
|
}
|
||||||
|
@ -103,6 +106,16 @@ std::vector<filter::filter_type> const& feature_type_style::image_filters() con
|
||||||
return filters_;
|
return filters_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<filter::filter_type>& feature_type_style::direct_image_filters()
|
||||||
|
{
|
||||||
|
return direct_filters_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<filter::filter_type> const& feature_type_style::direct_image_filters() const
|
||||||
|
{
|
||||||
|
return direct_filters_;
|
||||||
|
}
|
||||||
|
|
||||||
void feature_type_style::set_comp_op(composite_mode_e comp_op)
|
void feature_type_style::set_comp_op(composite_mode_e comp_op)
|
||||||
{
|
{
|
||||||
comp_op_ = comp_op;
|
comp_op_ = comp_op;
|
||||||
|
|
|
@ -430,22 +430,45 @@ void map_parser::parse_style(Map & map, xml_node const& sty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// image filters
|
// image filters
|
||||||
|
|
||||||
|
mapnik::image_filter_grammar<std::string::const_iterator,
|
||||||
|
std::vector<mapnik::filter::filter_type> > filter_grammar;
|
||||||
|
|
||||||
optional<std::string> filters = sty.get_opt_attr<std::string>("image-filters");
|
optional<std::string> filters = sty.get_opt_attr<std::string>("image-filters");
|
||||||
if (filters)
|
if (filters)
|
||||||
{
|
{
|
||||||
std::string filter_mode = *filters;
|
std::string filter_mode = *filters;
|
||||||
if (filter_mode.empty())
|
|
||||||
{
|
|
||||||
throw config_error("failed to parse empty image-filter");
|
|
||||||
}
|
|
||||||
std::string::const_iterator itr = filter_mode.begin();
|
std::string::const_iterator itr = filter_mode.begin();
|
||||||
std::string::const_iterator end = filter_mode.end();
|
std::string::const_iterator end = filter_mode.end();
|
||||||
mapnik::image_filter_grammar<std::string::const_iterator,std::vector<mapnik::filter::filter_type> > g;
|
|
||||||
|
|
||||||
bool result = boost::spirit::qi::phrase_parse(itr,end, g, boost::spirit::qi::ascii::space, style.image_filters());
|
bool result = boost::spirit::qi::phrase_parse(itr,end,
|
||||||
|
filter_grammar,
|
||||||
|
boost::spirit::qi::ascii::space,
|
||||||
|
style.image_filters());
|
||||||
if (!result || itr!=end)
|
if (!result || itr!=end)
|
||||||
{
|
{
|
||||||
throw config_error("failed to parse image-filter: '" + std::string(itr,end) + "'");
|
throw config_error("failed to parse image-filters: '" + std::string(itr,end) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// direct image filters (applied directly on main image buffer
|
||||||
|
// TODO : consider creating a separate XML node e.g
|
||||||
|
// <ImageFilter name="myfilter" op="blur emboss"/>
|
||||||
|
//
|
||||||
|
optional<std::string> direct_filters = sty.get_opt_attr<std::string>("direct-image-filters");
|
||||||
|
if (direct_filters)
|
||||||
|
{
|
||||||
|
std::string filter_mode = *direct_filters;
|
||||||
|
std::string::const_iterator itr = filter_mode.begin();
|
||||||
|
std::string::const_iterator end = filter_mode.end();
|
||||||
|
bool result = boost::spirit::qi::phrase_parse(itr,end,
|
||||||
|
filter_grammar,
|
||||||
|
boost::spirit::qi::ascii::space,
|
||||||
|
style.direct_image_filters());
|
||||||
|
if (!result || itr!=end)
|
||||||
|
{
|
||||||
|
throw config_error("failed to parse direct-image-filters: '" + std::string(itr,end) + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue