diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index 3839171aa..2fad73f17 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.hpp @@ -32,6 +32,7 @@ #include #include #include +#include // agg #include "agg_basics.h" @@ -39,7 +40,7 @@ #include "agg_pixfmt_rgba.h" #include "agg_scanline_u.h" #include "agg_blur.h" - +#include "agg_gradient_lut.h" // stl #include @@ -409,18 +410,22 @@ void apply_filter(Src & src, colorize_alpha const& op) { using namespace boost::gil; - mapnik::color const& c0 = op.c0_; - mapnik::color const& c1 = op.c1_; - uint8_t reds[256]; - uint8_t greens[256]; - uint8_t blues[256]; + agg::gradient_lut > grad_lut; + grad_lut.remove_all(); + std::size_t size = op.size(); + if (size < 2) return; - for (unsigned a=0; a < 256;++a) + double step = 1.0/(size-1); + double offset = 0.0; + BOOST_FOREACH( mapnik::color const& c, op) { - reds[a] = (c0.red() + (c1.red() - c0.red()) * a) >> 8; - greens[a] = (c0.green() + (c1.green() - c0.green()) * a) >> 8; - blues[a] = (c0.blue() + (c1.blue() - c0.blue()) * a) >> 8; + grad_lut.add_color(offset, agg::rgba(c.red()/256.0, + c.green()/256.0, + c.blue()/256.0, + c.alpha()/256.0)); + offset += step; } + grad_lut.build_lut(); rgba8_view_t src_view = rgba8_view(src); for (int y=0; y 0) { - - //r = (c0.red() + (c1.red() - c0.red()) * a) >> 8; - //g = (c0.green() + (c1.green() - c0.green()) * a) >> 8; - //b = (c0.blue() + (c1.blue() - c0.blue()) * a) >> 8; - r = (reds[a] * a + 255) >> 8; - g = (greens[a] * a + 255) >> 8; - b = (blues[a] * a + 255) >> 8; - + agg::rgba8 c = grad_lut[a]; + r = (c.r * a + 255) >> 8; + g = (c.g * a + 255) >> 8; + b = (c.b * a + 255) >> 8; #if 0 // rainbow r = 0; diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp index d98ad0e82..4c490f446 100644 --- a/include/mapnik/image_filter_grammar.hpp +++ b/include/mapnik/image_filter_grammar.hpp @@ -27,6 +27,7 @@ #include // mapnik #include +#include // stl #include @@ -45,7 +46,7 @@ struct image_filter_grammar : qi::rule, void(ContType&), qi::ascii::space_type> agg_blur_filter; qi::rule, void(ContType&), qi::ascii::space_type> hsla_filter; - qi::rule, void(ContType&), qi::ascii::space_type> colorize_alpha_filter; + qi::rule, void(ContType&), qi::ascii::space_type> colorize_alpha_filter; qi::rule no_args; qi::uint_parser< unsigned, 10, 1, 3 > radius_; css_color_grammar css_color_; diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index fe5b01875..b433e9dd5 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.hpp @@ -98,17 +98,16 @@ struct hsla double a1; }; -struct colorize_alpha +struct colorize_alpha : std::vector { + colorize_alpha() {} colorize_alpha(mapnik::color const& c0, mapnik::color const& c1) - : c0_(c0), - c1_(c1) { + this->push_back(c0); + this->push_back(c1); // TODO: support multiple color-stops // https://developer.mozilla.org/en-US/docs/CSS/linear-gradient } - mapnik::color c0_; - mapnik::color c1_; }; typedef boost::variant -#include // boost #include @@ -110,11 +109,11 @@ image_filter_grammar::image_filter_grammar() [push_back(_r1, construct(_a,_b,_c,_d,_e,_f,_g,_h))] ; - colorize_alpha_filter = lit("colorize-alpha") + colorize_alpha_filter = lit("colorize-alpha")[_a = construct()] >> lit('(') - >> css_color_[_a = _1] >> lit(',') - >> css_color_[_b = _1] >> lit(')') - [push_back(_r1,construct(_a,_b))] + >> css_color_[push_back(_a, _1)] + >> +(lit(',') >> css_color_[push_back(_a, _1)]) + >> lit(')') [push_back(_r1,_a)] ; no_args = -(lit('(') >> lit(')'));