SVG CSS: refactor unit value symbols table into separate header + add css_data member to svg_parser

This commit is contained in:
Artem Pavlenko 2020-02-04 15:02:41 +00:00
parent b6e567d87c
commit 27bf941211
3 changed files with 63 additions and 19 deletions

View file

@ -0,0 +1,54 @@
/*****************************************************************************
*
* This file is part of Mapnik (c++ mapping toolkit)
*
* Copyright (C) 2020 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_CSS_UNIT_VALUE_HPP
#define MAPNIK_CSS_UNIT_VALUE_HPP
#include <boost/spirit/home/x3.hpp>
namespace mapnik {
namespace x3 = boost::spirit::x3;
// units
struct css_unit_value : x3::symbols<double>
{
const double DPI = 90;
css_unit_value()
{
add
("px", 1.0)
("pt", DPI/72.0)
("pc", DPI/6.0)
("mm", DPI/25.4)
("cm", DPI/2.54)
("in", static_cast<double>(DPI))
//("em", 1.0/16.0) // default pixel size for body (usually 16px)
// ^^ this doesn't work currently as 'e' in 'em' interpreted as part of scientific notation.
;
}
};
} //mapnik
#endif //MAPNIK_CSS_GRAMMAR_X3_DEF_HPP

View file

@ -25,6 +25,7 @@
// mapnik
#include <mapnik/config.hpp>
#include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/svg/svg_path_attributes.hpp>
#include <mapnik/svg/svg_converter.hpp>
#include <mapnik/svg/svg_path_adapter.hpp>
@ -85,6 +86,7 @@ public:
bool ignore_;
std::map<std::string, gradient> gradient_map_;
std::map<std::string, boost::property_tree::detail::rapidxml::xml_node<char> const*> node_cache_;
mapnik::css_data css_data_;
agg::trans_affine viewbox_tr_{};
error_handler err_handler_;
};

View file

@ -21,8 +21,8 @@
*****************************************************************************/
#include <mapnik/debug.hpp>
#include <mapnik/css/css_unit_value.hpp>
#include <mapnik/color_factory.hpp>
#include <mapnik/css/css_grammar_x3.hpp>
#include <mapnik/svg/svg_parser.hpp>
#include <mapnik/svg/svg_path_parser.hpp>
#include <mapnik/config_error.hpp>
@ -279,17 +279,7 @@ double parse_svg_value(T & err_handler, const char* str, bool & is_percent)
{
namespace x3 = boost::spirit::x3;
double val = 0.0;
x3::symbols<double> units;
units.add
("px", 1.0)
("pt", DPI/72.0)
("pc", DPI/6.0)
("mm", DPI/25.4)
("cm", DPI/2.54)
("in", static_cast<double>(DPI))
//("em", 1.0/16.0) // default pixel size for body (usually 16px)
// ^^ this doesn't work currently as 'e' in 'em' interpreted as part of scientific notation.
;
css_unit_value units;
const char* cur = str; // phrase_parse mutates the first iterator
const char* end = str + std::strlen(str);
@ -463,25 +453,23 @@ void traverse_tree(svg_parser & parser, rapidxml::xml_node<char> const* node)
if ("style"_case == name)
{
// <style> element shouldn't have nested elements
// we only interested in DATA or CDATA
// <style> element is not expected to have nested elements
// we're only interested in DATA or CDATA
for (auto const* child = node->first_node();
child; child = child->next_sibling())
{
if (child->type() == rapidxml::node_data ||
child->type() == rapidxml::node_cdata)
{
std::cerr << "======================== STYLE " << std::endl;
mapnik::css_data css;
auto const grammar = mapnik::grammar();
auto const skipper = mapnik::skipper();
char const* first = child->value();
char const* last = first + child->value_size();
std::vector<std::string> classes;
bool result = boost::spirit::x3::phrase_parse(first, last, grammar, skipper, css);
if (result)
bool result = boost::spirit::x3::phrase_parse(first, last, grammar, skipper, parser.css_data_);
if (result && !parser.css_data_.empty())
{
print_css(css);
print_css(parser.css_data_);
}
}
}