SVG - add experimental "target" width and height which overwrite SVG's outermost "width" and "height" attributes [WIP]
This commit is contained in:
parent
21fd41b9a9
commit
792519e66a
6 changed files with 57 additions and 20 deletions
|
@ -56,6 +56,7 @@ public:
|
||||||
bool is_svg_uri(std::string const& path);
|
bool is_svg_uri(std::string const& path);
|
||||||
bool is_image_uri(std::string const& path);
|
bool is_image_uri(std::string const& path);
|
||||||
std::shared_ptr<marker const> find(std::string const& key, bool update_cache = false, bool strict = false);
|
std::shared_ptr<marker const> find(std::string const& key, bool update_cache = false, bool strict = false);
|
||||||
|
std::shared_ptr<marker const> find(std::string const& key, double width, double height, bool update_cache = false, bool strict = false);
|
||||||
void clear();
|
void clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -86,12 +86,14 @@ class MAPNIK_DECL svg_parser : private util::noncopyable
|
||||||
{
|
{
|
||||||
using error_handler = svg_parser_error_handler;
|
using error_handler = svg_parser_error_handler;
|
||||||
public:
|
public:
|
||||||
explicit svg_parser(svg_converter_type & path, bool strict = false);
|
explicit svg_parser(svg_converter_type & path, double width, double height, bool strict = false);
|
||||||
~svg_parser();
|
~svg_parser();
|
||||||
error_handler & err_handler();
|
error_handler & err_handler();
|
||||||
void parse(std::string const& filename);
|
void parse(std::string const& filename);
|
||||||
void parse_from_string(std::string const& svg);
|
void parse_from_string(std::string const& svg);
|
||||||
svg_converter_type & path_;
|
svg_converter_type & path_;
|
||||||
|
double width_;
|
||||||
|
double height_;
|
||||||
bool is_defs_;
|
bool is_defs_;
|
||||||
bool strict_;
|
bool strict_;
|
||||||
bool ignore_;
|
bool ignore_;
|
||||||
|
|
|
@ -144,6 +144,12 @@ struct visitor_create_marker
|
||||||
|
|
||||||
std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
|
std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
|
||||||
bool update_cache, bool strict)
|
bool update_cache, bool strict)
|
||||||
|
{
|
||||||
|
return find(uri, 0, 0, update_cache, strict);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri, double width, double height,
|
||||||
|
bool update_cache, bool strict)
|
||||||
{
|
{
|
||||||
if (uri.empty())
|
if (uri.empty())
|
||||||
{
|
{
|
||||||
|
@ -176,7 +182,7 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
|
||||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_path->source());
|
vertex_stl_adapter<svg_path_storage> stl_storage(marker_path->source());
|
||||||
svg_path_adapter svg_path(stl_storage);
|
svg_path_adapter svg_path(stl_storage);
|
||||||
svg_converter_type svg(svg_path, marker_path->attributes());
|
svg_converter_type svg(svg_path, marker_path->attributes());
|
||||||
svg_parser p(svg, strict);
|
svg_parser p(svg, width, height, strict);
|
||||||
p.parse_from_string(known_svg_string);
|
p.parse_from_string(known_svg_string);
|
||||||
|
|
||||||
if (!strict)
|
if (!strict)
|
||||||
|
@ -216,7 +222,7 @@ std::shared_ptr<mapnik::marker const> marker_cache::find(std::string const& uri,
|
||||||
vertex_stl_adapter<svg_path_storage> stl_storage(marker_path->source());
|
vertex_stl_adapter<svg_path_storage> stl_storage(marker_path->source());
|
||||||
svg_path_adapter svg_path(stl_storage);
|
svg_path_adapter svg_path(stl_storage);
|
||||||
svg_converter_type svg(svg_path, marker_path->attributes());
|
svg_converter_type svg(svg_path, marker_path->attributes());
|
||||||
svg_parser p(svg, strict);
|
svg_parser p(svg, width, height, strict);
|
||||||
p.parse(uri);
|
p.parse(uri);
|
||||||
|
|
||||||
if (!strict)
|
if (!strict)
|
||||||
|
|
|
@ -878,16 +878,28 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||||
viewbox vbox = {0, 0, 0, 0};
|
viewbox vbox = {0, 0, 0, 0};
|
||||||
bool has_percent_height = true;
|
bool has_percent_height = true;
|
||||||
bool has_percent_width = true;
|
bool has_percent_width = true;
|
||||||
|
bool overwrite_dimensions = false;
|
||||||
auto const* width_attr = node->first_attribute("width");
|
auto const* width_attr = node->first_attribute("width");
|
||||||
if (width_attr)
|
|
||||||
{
|
|
||||||
width = parse_svg_value(parser, width_attr->value(), has_percent_width);
|
|
||||||
}
|
|
||||||
auto const* height_attr = node->first_attribute("height");
|
auto const* height_attr = node->first_attribute("height");
|
||||||
if (height_attr)
|
|
||||||
|
if (parser.width_ > 0 && parser.height_ > 0) // overwrite SVG document dimensions
|
||||||
{
|
{
|
||||||
height = parse_svg_value(parser, height_attr->value(), has_percent_height);
|
has_percent_height = false;
|
||||||
|
has_percent_width = false;
|
||||||
|
overwrite_dimensions = true;
|
||||||
|
width = parser.width_;
|
||||||
|
height = parser.height_;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (width_attr)
|
||||||
|
{
|
||||||
|
width = parse_svg_value(parser, width_attr->value(), has_percent_width);
|
||||||
|
}
|
||||||
|
if (height_attr)
|
||||||
|
{
|
||||||
|
height = parse_svg_value(parser, height_attr->value(), has_percent_height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
parser.vbox_ = viewbox{0, 0, width, height} ;
|
parser.vbox_ = viewbox{0, 0, width, height} ;
|
||||||
auto const* viewbox_attr = node->first_attribute("viewBox");
|
auto const* viewbox_attr = node->first_attribute("viewBox");
|
||||||
|
@ -896,12 +908,13 @@ void parse_dimensions(svg_parser & parser, rapidxml::xml_node<char> const* node)
|
||||||
agg::trans_affine t{};
|
agg::trans_affine t{};
|
||||||
parser.vbox_ = vbox;
|
parser.vbox_ = vbox;
|
||||||
parser.normalized_diagonal_ = std::sqrt(vbox.width * vbox.width + vbox.height * vbox.height)/std::sqrt(2.0);
|
parser.normalized_diagonal_ = std::sqrt(vbox.width * vbox.width + vbox.height * vbox.height)/std::sqrt(2.0);
|
||||||
|
if (!overwrite_dimensions)
|
||||||
if (has_percent_width) width = vbox.width * width;
|
{
|
||||||
else if (!width_attr || width == 0) width = vbox.width;
|
if (has_percent_width) width = vbox.width * width;
|
||||||
if (has_percent_height) height = vbox.height * height;
|
else if (!width_attr || width == 0) width = vbox.width;
|
||||||
else if (!height_attr || height == 0) height = vbox.height;
|
if (has_percent_height) height = vbox.height * height;
|
||||||
|
else if (!height_attr || height == 0) height = vbox.height;
|
||||||
|
}
|
||||||
if (width > 0 && height > 0 && vbox.width > 0 && vbox.height > 0)
|
if (width > 0 && height > 0 && vbox.width > 0 && vbox.height > 0)
|
||||||
{
|
{
|
||||||
std::pair<unsigned,bool> preserve_aspect_ratio {xMidYMid, true};
|
std::pair<unsigned,bool> preserve_aspect_ratio {xMidYMid, true};
|
||||||
|
@ -1583,8 +1596,10 @@ void parse_linear_gradient(svg_parser & parser, rapidxml::xml_node<char> const*
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
svg_parser::svg_parser(svg_converter_type & path, bool strict)
|
svg_parser::svg_parser(svg_converter_type & path, double width, double height, bool strict)
|
||||||
: path_(path),
|
: path_(path),
|
||||||
|
width_(width),
|
||||||
|
height_(height),
|
||||||
is_defs_(false),
|
is_defs_(false),
|
||||||
ignore_(false),
|
ignore_(false),
|
||||||
css_style_(false),
|
css_style_(false),
|
||||||
|
|
|
@ -48,7 +48,7 @@ namespace // internal
|
||||||
: stl_storage(path.source())
|
: stl_storage(path.source())
|
||||||
, svg_path(stl_storage)
|
, svg_path(stl_storage)
|
||||||
, svg(svg_path, path.attributes())
|
, svg(svg_path, path.attributes())
|
||||||
, p(svg, strict)
|
, p(svg, 0, 0, strict)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
mapnik::svg::svg_parser* operator->()
|
mapnik::svg::svg_parser* operator->()
|
||||||
|
|
|
@ -152,7 +152,7 @@ struct main_marker_visitor
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string svg_name_;
|
std::string svg_name_;
|
||||||
double scale_factor_ = 1.0;
|
double scale_factor_;
|
||||||
bool verbose_;
|
bool verbose_;
|
||||||
bool auto_open_;
|
bool auto_open_;
|
||||||
};
|
};
|
||||||
|
@ -167,6 +167,8 @@ int main (int argc,char** argv)
|
||||||
int status = 0;
|
int status = 0;
|
||||||
std::vector<std::string> svg_files;
|
std::vector<std::string> svg_files;
|
||||||
mapnik::logger::instance().set_severity(mapnik::logger::error);
|
mapnik::logger::instance().set_severity(mapnik::logger::error);
|
||||||
|
double target_width = 0.0;
|
||||||
|
double target_height = 0.0;
|
||||||
double scale_factor = 1.0;
|
double scale_factor = 1.0;
|
||||||
std::string usage = "Usage: svg2png [options] <svg-file(s)>";
|
std::string usage = "Usage: svg2png [options] <svg-file(s)>";
|
||||||
try
|
try
|
||||||
|
@ -179,6 +181,8 @@ int main (int argc,char** argv)
|
||||||
("open,o","automatically open the file after rendering (os x only)")
|
("open,o","automatically open the file after rendering (os x only)")
|
||||||
("strict,s","enables strict SVG parsing")
|
("strict,s","enables strict SVG parsing")
|
||||||
("scale-factor", po::value<double>(), "provide scaling factor (default: 1.0)")
|
("scale-factor", po::value<double>(), "provide scaling factor (default: 1.0)")
|
||||||
|
("width", po::value<double>(), "width of the SVG document")
|
||||||
|
("height", po::value<double>(), "height of the SVG document")
|
||||||
("svg",po::value<std::vector<std::string> >(),"svg file to read")
|
("svg",po::value<std::vector<std::string> >(),"svg file to read")
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -219,6 +223,14 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
scale_factor = vm["scale-factor"].as<double>();
|
scale_factor = vm["scale-factor"].as<double>();
|
||||||
}
|
}
|
||||||
|
if (vm.count("width"))
|
||||||
|
{
|
||||||
|
target_width = vm["width"].as<double>();
|
||||||
|
}
|
||||||
|
if (vm.count("height"))
|
||||||
|
{
|
||||||
|
target_height = vm["height"].as<double>();
|
||||||
|
}
|
||||||
if (vm.count("svg"))
|
if (vm.count("svg"))
|
||||||
{
|
{
|
||||||
svg_files=vm["svg"].as< std::vector<std::string> >();
|
svg_files=vm["svg"].as< std::vector<std::string> >();
|
||||||
|
@ -242,7 +254,8 @@ int main (int argc,char** argv)
|
||||||
{
|
{
|
||||||
std::clog << "found: " << svg_name << "\n";
|
std::clog << "found: " << svg_name << "\n";
|
||||||
}
|
}
|
||||||
std::shared_ptr<mapnik::marker const> marker = mapnik::marker_cache::instance().find(svg_name, false, strict);
|
std::shared_ptr<mapnik::marker const> marker =
|
||||||
|
mapnik::marker_cache::instance().find(svg_name, target_width, target_height, false, strict);
|
||||||
main_marker_visitor visitor(svg_name, scale_factor, verbose, auto_open);
|
main_marker_visitor visitor(svg_name, scale_factor, verbose, auto_open);
|
||||||
status = mapnik::util::apply_visitor(visitor, *marker);
|
status = mapnik::util::apply_visitor(visitor, *marker);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue