svg - move stroke-dasharray setup into dash-array parser method

This commit is contained in:
artemp 2016-01-07 10:33:57 +00:00
parent bb8cd10751
commit ca83ca167d
6 changed files with 56 additions and 58 deletions

View file

@ -79,8 +79,7 @@ struct path_attributes
even_odd_flag(false), even_odd_flag(false),
visibility_flag(true), visibility_flag(true),
display_flag(true) display_flag(true)
{ {}
}
// Copy constructor // Copy constructor
path_attributes(path_attributes const& attr) path_attributes(path_attributes const& attr)

View file

@ -60,12 +60,10 @@
namespace mapnik { namespace mapnik {
namespace svg { namespace svg {
// Arbitrary linear gradient specified by two control points. Gradient
// value is taken as the normalised distance along the line segment
// represented by the two points.
/**
* Arbitrary linear gradient specified by two control points. Gradient
* value is taken as the normalised distance along the line segment
* represented by the two points.
*/
class linear_gradient_from_segment class linear_gradient_from_segment
{ {
public: public:
@ -105,14 +103,14 @@ template <typename VertexSource, typename AttributeSource, typename ScanlineRend
class svg_renderer_agg : util::noncopyable class svg_renderer_agg : util::noncopyable
{ {
public: public:
using curved_type = agg::conv_curve<VertexSource> ; using curved_type = agg::conv_curve<VertexSource>;
using curved_stroked_type = agg::conv_stroke<curved_type> ; using curved_stroked_type = agg::conv_stroke<curved_type>;
using curved_stroked_trans_type = agg::conv_transform<curved_stroked_type>; using curved_stroked_trans_type = agg::conv_transform<curved_stroked_type>;
using curved_trans_type = agg::conv_transform<curved_type> ; using curved_trans_type = agg::conv_transform<curved_type>;
using curved_trans_contour_type = agg::conv_contour<curved_trans_type> ; using curved_trans_contour_type = agg::conv_contour<curved_trans_type>;
using renderer_base = agg::renderer_base<PixelFormat> ; using renderer_base = agg::renderer_base<PixelFormat>;
using vertex_source_type = VertexSource ; using vertex_source_type = VertexSource;
using attribute_source_type = AttributeSource ; using attribute_source_type = AttributeSource;
svg_renderer_agg(VertexSource & source, AttributeSource const& attributes) svg_renderer_agg(VertexSource & source, AttributeSource const& attributes)
: source_(source), : source_(source),
@ -191,11 +189,11 @@ public:
// scale everything up since agg turns things into integers a bit too soon // scale everything up since agg turns things into integers a bit too soon
int scaleup=255; int scaleup=255;
radius*=scaleup; radius *= scaleup;
x1*=scaleup; x1 *= scaleup;
y1*=scaleup; y1 *= scaleup;
x2*=scaleup; x2 *= scaleup;
y2*=scaleup; y2 *= scaleup;
transform.scale(scaleup,scaleup); transform.scale(scaleup,scaleup);
interpolator_type span_interpolator(transform); interpolator_type span_interpolator(transform);
@ -217,10 +215,10 @@ public:
color_func_type>; color_func_type>;
// scale everything up since agg turns things into integers a bit too soon // scale everything up since agg turns things into integers a bit too soon
int scaleup=255; int scaleup=255;
x1*=scaleup; x1 *= scaleup;
y1*=scaleup; y1 *= scaleup;
x2*=scaleup; x2 *= scaleup;
y2*=scaleup; y2 *= scaleup;
transform.scale(scaleup,scaleup); transform.scale(scaleup,scaleup);
@ -288,7 +286,8 @@ public:
if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT) if(attr.fill_gradient.get_gradient_type() != NO_GRADIENT)
{ {
render_gradient(ras, sl, ren, attr.fill_gradient, transform, attr.fill_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index); render_gradient(ras, sl, ren, attr.fill_gradient, transform,
attr.fill_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
} }
else else
{ {
@ -324,7 +323,8 @@ public:
if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT) if(attr.stroke_gradient.get_gradient_type() != NO_GRADIENT)
{ {
render_gradient(ras, sl, ren, attr.stroke_gradient, transform, attr.stroke_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index); render_gradient(ras, sl, ren, attr.stroke_gradient, transform,
attr.stroke_opacity * attr.opacity * opacity, symbol_bbox, curved_trans, attr.index);
} }
else else
{ {

View file

@ -317,12 +317,8 @@ struct evaluate_expression_wrapper<mapnik::dash_array>
mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr); mapnik::value_type val = util::apply_visitor(mapnik::evaluate<T2,mapnik::value_type,T3>(feature,vars), expr);
if (val.is_null()) return dash_array(); if (val.is_null()) return dash_array();
dash_array dash; dash_array dash;
std::vector<double> buf;
std::string str = val.to_string(); std::string str = val.to_string();
if (util::parse_dasharray(str,buf)) util::parse_dasharray(str,dash);
{
util::add_dashes(buf,dash);
}
return dash; return dash;
} }
}; };

View file

@ -404,9 +404,8 @@ struct set_symbolizer_property_impl<Symbolizer,dash_array,false>
boost::optional<std::string> str = node.get_opt_attr<std::string>(name); boost::optional<std::string> str = node.get_opt_attr<std::string>(name);
if (str) if (str)
{ {
std::vector<double> buf;
dash_array dash; dash_array dash;
if (util::parse_dasharray(*str,buf) && util::add_dashes(buf,dash)) if (util::parse_dasharray(*str,dash))
{ {
put(sym,key,dash); put(sym,key,dash);
} }

View file

@ -23,32 +23,13 @@
#ifndef MAPNIK_UTIL_DASHARRAY_PARSER_HPP #ifndef MAPNIK_UTIL_DASHARRAY_PARSER_HPP
#define MAPNIK_UTIL_DASHARRAY_PARSER_HPP #define MAPNIK_UTIL_DASHARRAY_PARSER_HPP
#include <mapnik/symbolizer_base.hpp>
#include <vector> #include <vector>
#include <string> #include <string>
namespace mapnik { namespace util { namespace mapnik { namespace util {
bool parse_dasharray(std::string const& value, std::vector<double>& dasharray); bool parse_dasharray(std::string const& value, dash_array & dash);
inline bool add_dashes(std::vector<double> & buf, std::vector<std::pair<double,double> > & dash)
{
if (buf.empty()) return false;
size_t size = buf.size();
if (size % 2 == 1)
{
buf.insert(buf.end(),buf.begin(),buf.end());
}
std::vector<double>::const_iterator pos = buf.begin();
while (pos != buf.end())
{
if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0
{
dash.emplace_back(*pos,*(pos + 1));
}
pos +=2;
}
return !buf.empty();
}
}} }}

View file

@ -36,7 +36,29 @@ namespace mapnik {
namespace util { namespace util {
bool parse_dasharray(std::string const& value, std::vector<double>& dasharray) namespace {
inline bool setup_dashes(std::vector<double> & buf, dash_array & dash)
{
if (buf.empty()) return false;
size_t size = buf.size();
if (size % 2 == 1)
{
buf.insert(buf.end(),buf.begin(),buf.end());
}
std::vector<double>::const_iterator pos = buf.begin();
while (pos != buf.end())
{
if (*pos > 0.0 || *(pos+1) > 0.0) // avoid both dash and gap eq 0.0
{
dash.emplace_back(*pos,*(pos + 1));
}
pos +=2;
}
return !buf.empty();
}
}
bool parse_dasharray(std::string const& value, dash_array & dash)
{ {
using namespace boost::spirit; using namespace boost::spirit;
qi::double_type double_; qi::double_type double_;
@ -49,18 +71,19 @@ bool parse_dasharray(std::string const& value, std::vector<double>& dasharray)
// dasharray ::= (length | percentage) (comma-wsp dasharray)? // dasharray ::= (length | percentage) (comma-wsp dasharray)?
// no support for 'percentage' as viewport is unknown at load_map // no support for 'percentage' as viewport is unknown at load_map
// //
std::vector<double> buf;
auto first = value.begin(); auto first = value.begin();
auto last = value.end(); auto last = value.end();
bool r = qi::phrase_parse(first, last, bool r = qi::phrase_parse(first, last,
(double_[boost::phoenix::push_back(boost::phoenix::ref(dasharray), _1)] % (double_[boost::phoenix::push_back(boost::phoenix::ref(buf), _1)] %
no_skip[char_(", ")] no_skip[char_(", ")]
| lit("none")), | lit("none")),
space); space);
if (first != last) if (r && first == last)
{ {
return false; return setup_dashes(buf, dash);
} }
return r; return false;
} }
} // end namespace util } // end namespace util