Merge pull request #3075 from mapycz/fix-parsing-hex-colors

fix parsing colors in hexadecimal notation
This commit is contained in:
Blake Thompson 2015-09-18 09:06:02 -05:00
commit 4e4c1bc30e
5 changed files with 183 additions and 5 deletions

View file

@ -16,6 +16,7 @@ Released: YYYY XX, 2015
- Visual tests: new command line arguments `--agg`, `--cairo`, `--svg`, `--grid` for selecting renderers (https://github.com/mapnik/mapnik/pull/3074)
- Visual tests: new command line argument `--scale-factor` or abbreviated `-s` for setting scale factor (https://github.com/mapnik/mapnik/pull/3074)
- Fixed parsing colors in hexadecimal notation (https://github.com/mapnik/mapnik/pull/3075)
## 3.0.5

View file

@ -37,6 +37,7 @@
#pragma GCC diagnostic ignored "-Wconversion"
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_lexeme.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>

View file

@ -39,6 +39,7 @@ css_color_grammar<Iterator>::css_color_grammar()
qi::_a_type _a;
qi::_b_type _b;
qi::_c_type _c;
qi::lexeme_type lexeme;
ascii::no_case_type no_case;
using phoenix::at_c;
@ -49,18 +50,18 @@ css_color_grammar<Iterator>::css_color_grammar()
| hex_color_small
| no_case[named];
hex_color = lit('#')
hex_color = lexeme[ lit('#')
>> hex2 [ at_c<0>(_val) = _1 ]
>> hex2 [ at_c<1>(_val) = _1 ]
>> hex2 [ at_c<2>(_val) = _1 ]
>>-hex2 [ at_c<3>(_val) = _1 ]
>>-hex2 [ at_c<3>(_val) = _1 ] ]
;
hex_color_small = lit('#')
hex_color_small = lexeme[ lit('#')
>> hex1 [ at_c<0>(_val) = _1 | _1 << 4 ]
>> hex1 [ at_c<1>(_val) = _1 | _1 << 4 ]
>> hex1 [ at_c<2>(_val) = _1 | _1 << 4 ]
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ]
>>-hex1 [ at_c<3>(_val) = _1 | _1 << 4 ] ]
;
rgba_color = lit("rgb") >> -lit('a')

View file

@ -1,5 +1,6 @@
#include "catch.hpp"
#include <mapnik/css_color_grammar.hpp>
#include <mapnik/css_color_grammar_impl.hpp>
#include <mapnik/safe_cast.hpp>
TEST_CASE("css color") {
@ -35,4 +36,132 @@ TEST_CASE("css color") {
CHECK( c.green() == 0 );
CHECK( c.blue() == 0 );
}
SECTION("hex colors")
{
mapnik::css_color_grammar<std::string::const_iterator> color_grammar;
boost::spirit::qi::ascii::space_type space;
{
std::string s("#abcdef");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xff );
CHECK( c.red() == 0xab );
CHECK( c.green() == 0xcd );
CHECK( c.blue() == 0xef );
}
{
std::string s("#abcdef12");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0x12 );
CHECK( c.red() == 0xab );
CHECK( c.green() == 0xcd );
CHECK( c.blue() == 0xef );
}
{
std::string s(" #abcdef");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xff );
CHECK( c.red() == 0xab );
CHECK( c.green() == 0xcd );
CHECK( c.blue() == 0xef );
}
{
std::string s(" #abcdef12");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0x12 );
CHECK( c.red() == 0xab );
CHECK( c.green() == 0xcd );
CHECK( c.blue() == 0xef );
}
{
std::string s("# abcdef");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("# abcdef12");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("#ab cdef");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("#ab cdef12");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
// hex_color_small
{
std::string s("#abc");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xff );
CHECK( c.red() == 0xaa );
CHECK( c.green() == 0xbb );
CHECK( c.blue() == 0xcc );
}
{
std::string s("#abcd");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xdd );
CHECK( c.red() == 0xaa );
CHECK( c.green() == 0xbb );
CHECK( c.blue() == 0xcc );
}
{
std::string s(" #abc");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xff );
CHECK( c.red() == 0xaa );
CHECK( c.green() == 0xbb );
CHECK( c.blue() == 0xcc );
}
{
std::string s(" #abcd");
mapnik::color c;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space, c) );
CHECK( c.alpha() == 0xdd );
CHECK( c.red() == 0xaa );
CHECK( c.green() == 0xbb );
CHECK( c.blue() == 0xcc );
}
{
std::string s("# abc");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("# abcd");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("#a bc");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
{
std::string s("#a bcd");
CHECK( !boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), color_grammar, space) );
}
}
}

View file

@ -6,6 +6,9 @@
#include <mapnik/color.hpp>
#include <mapnik/image_filter.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_filter_grammar.hpp>
#include <mapnik/image_filter_grammar_impl.hpp>
#include <mapnik/css_color_grammar_impl.hpp>
TEST_CASE("image filter") {
@ -388,6 +391,49 @@ SECTION("test colorize-alpha - two color with transparency") {
} // END SECTION
SECTION("test colorize-alpha - parsing correct input") {
mapnik::image_filter_grammar<std::string::const_iterator, std::vector<mapnik::filter::filter_type>> filter_grammar;
boost::spirit::qi::ascii::space_type space;
std::vector<mapnik::filter::filter_type> f;
std::string s("colorize-alpha(#0000ff 0%, #00ff00 100%)");
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), filter_grammar, space, f) );
mapnik::filter::colorize_alpha const & ca = mapnik::util::get<mapnik::filter::colorize_alpha>(f.front());
{
mapnik::filter::color_stop const & s = ca[0];
CHECK( s.color.alpha() == 0xff );
CHECK( s.color.red() == 0x00 );
CHECK( s.color.green() == 0x00 );
CHECK( s.color.blue() == 0xff );
CHECK( s.offset == 0.0 );
}
{
mapnik::filter::color_stop const & s = ca[1];
CHECK( s.color.alpha() == 0xff );
CHECK( s.color.red() == 0x00 );
CHECK( s.color.green() == 0xff );
CHECK( s.color.blue() == 0x00 );
CHECK( s.offset == 1.0 );
}
} // END SECTION
SECTION("test colorize-alpha - parsing incorrect input") {
mapnik::image_filter_grammar<std::string::const_iterator, std::vector<mapnik::filter::filter_type>> filter_grammar;
boost::spirit::qi::ascii::space_type space;
std::string s("colorize-alpha(#0000ff 0%, #00ff00 00 100%)");
std::string::const_iterator itr = s.cbegin();
std::string::const_iterator end = s.cend();
std::vector<mapnik::filter::filter_type> f;
CHECK( boost::spirit::qi::phrase_parse(s.cbegin(), s.cend(), filter_grammar, space, f) );
CHECK( f.empty() );
CHECK( itr != end );
} // END SECTION
SECTION("test color-blind-protanope") {
mapnik::image_rgba8 im(2,2);