diff --git a/CHANGELOG.md b/CHANGELOG.md index 571db49a1..a177314c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ For a complete change history, see the git log. - Added `premultiplied` property on mapnik::image_32 / mapnik.Image to enable knowledge of premultiplied status of image buffer. +- Added `scale-hsla` image-filter that allows scaling colors in HSL color space. RGB is converted to HSL (hue-saturation-lightness) and then each value (and the original alpha value) is stretched based on the specified scaling values. An example syntax is `scale-hsla(0,1,0,1,0,1,0,1)` which means no change because the full range will be kept (0 for lowest, 1 for highest). Other examples are: 1) `scale-hsla(0,0,0,1,0,1,0,1)` which would force all colors to be red in hue in the same way `scale-hsla(1,1,0,1,0,1,0,1)` would, 2) `scale-hsla(0,1,1,1,0,1,0,1)` which would cause all colors to become fully saturated, 3) `scale-hsla(0,1,1,1,0,1,.5,1)` which would force no colors to be any more transparent than half, and 4) `scale-hsla(0,1,1,1,0,1,0,.5)` which would force all colors to be at least half transparent. (#1954) + ## 2.2.0 Released June 3rd, 2013 diff --git a/include/mapnik/image_filter.hpp b/include/mapnik/image_filter.hpp index c11bd2e66..3946cb8ad 100644 --- a/include/mapnik/image_filter.hpp +++ b/include/mapnik/image_filter.hpp @@ -483,9 +483,8 @@ void apply_filter(Src & src, colorize_alpha const& op) } } -/* template -void apply_filter(Src & src, hsla const& transform) +void apply_filter(Src & src, scale_hsla const& transform) { using namespace boost::gil; bool tinting = !transform.is_identity(); @@ -504,16 +503,24 @@ void apply_filter(Src & src, hsla const& transform) uint8_t & g = get_color(src_it[x], green_t()); uint8_t & b = get_color(src_it[x], blue_t()); uint8_t & a = get_color(src_it[x], alpha_t()); - double a2 = a/255.0; + double a2 = static_cast(a)/255.0; double a1 = a2; + bool alpha_modified = false; if (set_alpha && a2 > 0.01) { a2 = transform.a0 + (a2 * (transform.a1 - transform.a0)); - a = static_cast(std::floor((a2 * 255.0) +.5)); - if (a > 255) a = 255; - if (a < 0) a = 0; + if (a2 <= 0) + { + a = 0; + } + else + { + a = static_cast(std::floor((a2 * 255.0) +.5)); + if (a > 255) a = 255; + } + alpha_modified = true; } - if (tinting && a2 > 0.01) + if (tinting && a > 1) { double h; double s; @@ -534,12 +541,12 @@ void apply_filter(Src & src, hsla const& transform) double h2 = transform.h0 + (h * (transform.h1 - transform.h0)); double s2 = transform.s0 + (s * (transform.s1 - transform.s0)); double l2 = transform.l0 + (l * (transform.l1 - transform.l0)); - if (h2 > 1) { std::clog << "h2: " << h2 << "\n"; h2 = 1; } - else if (h2 < 0) { std::clog << "h2: " << h2 << "\n"; h2 = 0; } - if (s2 > 1) { std::clog << "h2: " << h2 << "\n"; s2 = 1; } - else if (s2 < 0) { std::clog << "s2: " << s2 << "\n"; s2 = 0; } - if (l2 > 1) { std::clog << "h2: " << h2 << "\n"; l2 = 1; } - else if (l2 < 0) { std::clog << "l2: " << l2 << "\n"; l2 = 0; } + if (h2 > 1) { h2 = 1; } + else if (h2 < 0) { h2 = 0; } + if (s2 > 1) { s2 = 1; } + else if (s2 < 0) { s2 = 0; } + if (l2 > 1) { l2 = 1; } + else if (l2 < 0) { l2 = 0; } hsl2rgb(h2,s2,l2,r,g,b); // premultiply // we only work with premultiplied source, @@ -548,7 +555,7 @@ void apply_filter(Src & src, hsla const& transform) g *= a2; b *= a2; } - else + else if (alpha_modified) { // demultiply if (a1 <= 0.0) @@ -573,7 +580,6 @@ void apply_filter(Src & src, hsla const& transform) } } } -*/ template void apply_filter(Src & src, gray const& op) diff --git a/include/mapnik/image_filter_grammar.hpp b/include/mapnik/image_filter_grammar.hpp index 4f4523278..26156fbf1 100644 --- a/include/mapnik/image_filter_grammar.hpp +++ b/include/mapnik/image_filter_grammar.hpp @@ -67,8 +67,8 @@ struct image_filter_grammar : qi::rule start; qi::rule filter; 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> scale_hsla_filter; qi::rule, void(ContType&), qi::ascii::space_type> colorize_alpha_filter; qi::rule no_args; qi::uint_parser< unsigned, 10, 1, 3 > radius_; diff --git a/include/mapnik/image_filter_types.hpp b/include/mapnik/image_filter_types.hpp index d464a30ce..e5f0b5db6 100644 --- a/include/mapnik/image_filter_types.hpp +++ b/include/mapnik/image_filter_types.hpp @@ -28,7 +28,6 @@ #include // boost #include -#include // stl #include #include @@ -54,10 +53,9 @@ struct agg_stack_blur unsigned ry; }; -/* -struct hsla +struct scale_hsla { - hsla(double _h0, double _h1, + scale_hsla(double _h0, double _h1, double _s0, double _s1, double _l0, double _l1, double _a0, double _a1) : @@ -81,14 +79,6 @@ struct hsla return (a0 == 0 && a1 == 1); } - std::string to_string() const { - std::ostringstream s; - s << h0 << "x" << h1 << ";" - << s0 << "x" << s1 << ";" - << l0 << "x" << l1 << ";" - << a0 << "x" << a1; - return s.str(); - } double h0; double h1; double s0; @@ -98,7 +88,6 @@ struct hsla double a0; double a1; }; -*/ struct color_stop { @@ -124,7 +113,7 @@ typedef boost::variant filter_type; inline std::ostream& operator<< (std::ostream& os, blur) @@ -145,16 +134,14 @@ inline std::ostream& operator<< (std::ostream& os, agg_stack_blur const& filter) return os; } -/* -inline std::ostream& operator<< (std::ostream& os, hsla const& filter) +inline std::ostream& operator<< (std::ostream& os, scale_hsla const& filter) { - os << "hsla(" << filter.h0 << 'x' << filter.h1 << ':' + os << "hsla-transform(" << filter.h0 << 'x' << filter.h1 << ':' << filter.s0 << 'x' << filter.s1 << ':' << filter.l0 << 'x' << filter.l1 << ':' << filter.a0 << 'x' << filter.a1 << ')'; return os; } -*/ inline std::ostream& operator<< (std::ostream& os, emboss) { @@ -198,7 +185,27 @@ inline std::ostream& operator<< (std::ostream& os, invert) return os; } -inline std::ostream& operator<< (std::ostream& os, filter_type const& filter); +template +struct to_string_visitor : boost::static_visitor +{ + to_string_visitor(Out & out) + : out_(out) {} + + template + void operator () (T const& filter_tag) + { + out_ << filter_tag; + } + + Out & out_; +}; + +inline std::ostream& operator<< (std::ostream& os, filter_type const& filter) +{ + to_string_visitor visitor(os); + boost::apply_visitor(visitor, filter); + return os; +} MAPNIK_DECL bool generate_image_filters(std::back_insert_iterator & sink, std::vector const& v); diff --git a/src/image_filter_grammar.cpp b/src/image_filter_grammar.cpp index b50807129..a17191d14 100644 --- a/src/image_filter_grammar.cpp +++ b/src/image_filter_grammar.cpp @@ -88,8 +88,8 @@ image_filter_grammar::image_filter_grammar() | agg_blur_filter(_val) | - //hsla_filter(_val) - //| + scale_hsla_filter(_val) + | colorize_alpha_filter(_val) ; @@ -100,16 +100,14 @@ image_filter_grammar::image_filter_grammar() [push_back(_r1,construct(_a,_b))] ; - /* - hsla_filter = lit("hsla") + scale_hsla_filter = lit("scale-hsla") >> lit('(') - >> double_[_a = _1] >> lit('x') >> double_[_b = _1] >> lit(';') - >> double_[_c = _1] >> lit('x') >> double_[_d = _1] >> lit(';') - >> double_[_e = _1] >> lit('x') >> double_[_f = _1] >> lit(';') - >> double_[_g = _1] >> lit('x') >> double_[_h = _1] >> lit(')') - [push_back(_r1, construct(_a,_b,_c,_d,_e,_f,_g,_h))] + >> double_[_a = _1] >> lit(',') >> double_[_b = _1] >> lit(',') + >> double_[_c = _1] >> lit(',') >> double_[_d = _1] >> lit(',') + >> double_[_e = _1] >> lit(',') >> double_[_f = _1] >> lit(',') + >> double_[_g = _1] >> lit(',') >> double_[_h = _1] >> lit(')') + [push_back(_r1, construct(_a,_b,_c,_d,_e,_f,_g,_h))] ; - */ colorize_alpha_filter = lit("colorize-alpha")[_a = construct()] >> lit('(') diff --git a/src/image_filter_types.cpp b/src/image_filter_types.cpp index a9bc4c3ce..9ffa0ad91 100644 --- a/src/image_filter_types.cpp +++ b/src/image_filter_types.cpp @@ -34,28 +34,6 @@ namespace mapnik { namespace filter { -template -struct to_string_visitor : boost::static_visitor -{ - to_string_visitor(Out & out) - : out_(out) {} - - template - void operator () (T const& filter_tag) - { - out_ << filter_tag; - } - - Out & out_; -}; - -inline std::ostream& operator<< (std::ostream& os, filter_type const& filter) -{ - to_string_visitor visitor(os); - boost::apply_visitor(visitor, filter); - return os; -} - bool generate_image_filters(std::back_insert_iterator& sink, std::vector const& filters) { using boost::spirit::karma::stream; diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-agg-reference.png index 24c587122..0fe1cacfb 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-cairo-reference.png index ffa40ac2d..761743e75 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-agg-reference.png index 1594a246c..f766c3a28 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-cairo-reference.png index 018a553b7..f6c31d6ca 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-257-256-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-agg-reference.png index 5b28189bf..7da16b1cd 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-cairo-reference.png index cbfda129c..e991deb99 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-agg-reference.png index c1b3387f7..cdc496257 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-cairo-reference.png index fb4489a65..a4aec0749 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-400-600-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-agg-reference.png index d66a6a861..2a65704af 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-cairo-reference.png index cf585a900..a7bc35af6 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-1.0-cairo-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-agg-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-agg-reference.png index c968382d0..22d92db8d 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-agg-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-agg-reference.png differ diff --git a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-cairo-reference.png b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-cairo-reference.png index b242281b5..784c23c62 100644 Binary files a/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-cairo-reference.png and b/tests/visual_tests/images/marker-with-background-image-and-hsla-transform-600-400-2.0-cairo-reference.png differ diff --git a/tests/visual_tests/styles/marker-with-background-image-and-hsla-transform.xml b/tests/visual_tests/styles/marker-with-background-image-and-hsla-transform.xml index 31110e31c..4d691fbaa 100644 --- a/tests/visual_tests/styles/marker-with-background-image-and-hsla-transform.xml +++ b/tests/visual_tests/styles/marker-with-background-image-and-hsla-transform.xml @@ -1,6 +1,9 @@ -