+ impl dasharray parser (supports 'none')

+ skip 0,0 dashes in load_map
This commit is contained in:
Artem Pavlenko 2012-03-23 11:56:23 +00:00
parent d76136ba40
commit 38fafc14bc
2 changed files with 81 additions and 28 deletions

View file

@ -0,0 +1,62 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2012 Artem Pavlenko
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*****************************************************************************/
#ifndef MAPNIK_UTIL_DASHARRAY_PARSER_HPP
#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace mapnik { namespace util {
template <typename Iterator>
bool parse_dasharray(Iterator first, Iterator last, std::vector<double>& dasharray)
{
using qi::double_;
using qi::phrase_parse;
using qi::_1;
using qi::lit;
using ascii::space;
using phoenix::push_back;
// SVG
// dasharray ::= (length | percentage) (comma-wsp dasharray)?
// no support for 'percentage' as viewport is unknown at load_map
//
bool r = phrase_parse(first, last,
(
lit("none") | (double_[push_back(phoenix::ref(dasharray), _1)]
>> *(',' >> double_[push_back(phoenix::ref(dasharray), _1)]))
)
,
space);
if (first != last)
return false;
return r;
}
}}
#endif // MAPNIK_UTIL_DASHARRAY_PARSER_HPP

View file

@ -50,6 +50,7 @@
#include <mapnik/symbolizer.hpp>
#include <mapnik/rule.hpp>
#include <mapnik/config_error.hpp>
#include <mapnik/util/dasharray_parser.hpp>
// boost
#include <boost/optional.hpp>
@ -1229,39 +1230,29 @@ void map_parser::parse_stroke(stroke & strk, xml_node const & sym)
optional<std::string> str = sym.get_opt_attr<std::string>("stroke-dasharray");
if (str)
{
tokenizer<> tok (*str);
std::vector<double> dash_array;
tokenizer<>::iterator itr = tok.begin();
for (; itr != tok.end(); ++itr)
if (util::parse_dasharray((*str).begin(),(*str).end(),dash_array))
{
try
if (!dash_array.empty())
{
double f = boost::lexical_cast<double>(*itr);
dash_array.push_back(f);
}
catch (boost::bad_lexical_cast &)
{
throw config_error(std::string("Failed to parse dasharray ") +
"'. Expected a " +
"list of floats but got '" + (*str) + "'");
}
}
if (dash_array.size())
{
size_t size = dash_array.size();
if (size % 2)
{
for (size_t i=0; i < size ;++i)
size_t size = dash_array.size();
if (size % 2 == 1)
dash_array.insert(dash_array.end(),dash_array.begin(),dash_array.end());
std::vector<double>::const_iterator pos = dash_array.begin();
while (pos != dash_array.end())
{
dash_array.push_back(dash_array[i]);
if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0
strk.add_dash(*pos,*(pos + 1));
pos +=2;
}
}
std::vector<double>::const_iterator pos = dash_array.begin();
while (pos != dash_array.end())
{
strk.add_dash(*pos,*(pos + 1));
pos +=2;
}
}
}
else
{
throw config_error(std::string("Failed to parse dasharray ") +
"'. Expected a " +
"list of floats or 'none' but got '" + (*str) + "'");
}
}
}