SVG - refactor and minimise internal group usage [WIP] [skip ci]
This commit is contained in:
parent
8c04fb1262
commit
5f4711a019
4 changed files with 35 additions and 21 deletions
|
@ -65,6 +65,8 @@ class svg_converter : util::noncopyable
|
|||
svg_height_(0.0)
|
||||
{}
|
||||
|
||||
void set_opacity(double opacity) { svg_group_.opacity = opacity; }
|
||||
|
||||
void begin_group()
|
||||
{
|
||||
current_group_->elements.emplace_back(group {cur_attr().opacity, {}, current_group_});
|
||||
|
|
|
@ -145,10 +145,27 @@ class renderer_agg : util::noncopyable
|
|||
box2d<double> const& symbol_bbox)
|
||||
|
||||
{
|
||||
double adjusted_opacity = opacity * svg_group_.opacity; // adjust top level opacity
|
||||
if (adjusted_opacity < 1.0)
|
||||
{
|
||||
mapnik::image_rgba8 im(ren.width(), ren.height(), true, true);
|
||||
agg::rendering_buffer buf(im.bytes(), im.width(), im.height(), im.row_size());
|
||||
PixelFormat pixf(buf);
|
||||
Renderer ren_g(pixf);
|
||||
for (auto const& elem : svg_group_.elements)
|
||||
{
|
||||
mapbox::util::apply_visitor(group_renderer<Rasterizer, Scanline, Renderer>
|
||||
(*this, ras, sl, ren, mtx, opacity, symbol_bbox, true), elem);
|
||||
(*this, ras, sl, ren_g, mtx, symbol_bbox), elem);
|
||||
}
|
||||
ren.blend_from(ren_g.ren(), 0, 0, 0, unsigned(adjusted_opacity * 255));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (auto const& elem : svg_group_.elements)
|
||||
{
|
||||
mapbox::util::apply_visitor(group_renderer<Rasterizer, Scanline, Renderer>
|
||||
(*this, ras, sl, ren, mtx, symbol_bbox), elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -158,17 +175,13 @@ class renderer_agg : util::noncopyable
|
|||
group_renderer(renderer_agg& renderer,
|
||||
Rasterizer & ras, Scanline& sl, Renderer& ren,
|
||||
agg::trans_affine const& mtx,
|
||||
double opacity,
|
||||
box2d<double> const& symbol_bbox,
|
||||
bool first = false)
|
||||
box2d<double> const& symbol_bbox)
|
||||
: renderer_(renderer),
|
||||
ras_(ras),
|
||||
sl_(sl),
|
||||
ren_(ren),
|
||||
mtx_(mtx),
|
||||
opacity_(opacity),
|
||||
symbol_bbox_(symbol_bbox),
|
||||
first_(first)
|
||||
symbol_bbox_(symbol_bbox)
|
||||
{}
|
||||
|
||||
void render_gradient(Rasterizer& ras,
|
||||
|
@ -281,7 +294,6 @@ class renderer_agg : util::noncopyable
|
|||
void operator() (group const& g) const
|
||||
{
|
||||
double opacity = g.opacity;
|
||||
if (first_) opacity *= opacity_; // adjust top level opacity
|
||||
if (opacity < 1.0)
|
||||
{
|
||||
mapnik::image_rgba8 im(ren_.width(), ren_.height(), true, true);
|
||||
|
@ -291,7 +303,7 @@ class renderer_agg : util::noncopyable
|
|||
for (auto const& elem : g.elements)
|
||||
{
|
||||
mapbox::util::apply_visitor(
|
||||
group_renderer(renderer_, ras_, sl_, ren, mtx_, opacity_, symbol_bbox_), elem);
|
||||
group_renderer(renderer_, ras_, sl_, ren, mtx_, symbol_bbox_), elem);
|
||||
}
|
||||
ren_.blend_from(ren.ren(), 0, 0, 0, unsigned(opacity * 255));
|
||||
}
|
||||
|
@ -300,7 +312,7 @@ class renderer_agg : util::noncopyable
|
|||
for (auto const& elem : g.elements)
|
||||
{
|
||||
mapbox::util::apply_visitor(
|
||||
group_renderer(renderer_, ras_, sl_, ren_, mtx_, opacity_, symbol_bbox_), elem);
|
||||
group_renderer(renderer_, ras_, sl_, ren_, mtx_, symbol_bbox_), elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -463,9 +475,7 @@ class renderer_agg : util::noncopyable
|
|||
Scanline& sl_;
|
||||
Renderer& ren_;
|
||||
agg::trans_affine const& mtx_;
|
||||
double opacity_;
|
||||
box2d<double> const& symbol_bbox_;
|
||||
bool first_;
|
||||
};
|
||||
|
||||
#if defined(GRID_RENDERER)
|
||||
|
|
|
@ -189,6 +189,7 @@ bool push_explicit_style(svg::group const& src,
|
|||
auto stroke_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
|
||||
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
|
||||
bool success = false;
|
||||
dst.opacity = src.opacity;
|
||||
if (fill_color || fill_opacity || stroke_color || stroke_width || stroke_opacity)
|
||||
{
|
||||
for (auto const& elem : src.elements)
|
||||
|
|
|
@ -548,7 +548,9 @@ void traverse_tree(svg_parser& parser, rapidxml::xml_node<char> const* node)
|
|||
if (parser.css_style_)
|
||||
process_css(parser, node);
|
||||
parse_attr(parser, node);
|
||||
if (parser.path_.cur_attr().opacity < 1.0) parser.path_.begin_group();
|
||||
parse_use(parser, node);
|
||||
if (parser.path_.cur_attr().opacity < 1.0) parser.path_.end_group();
|
||||
parser.path_.pop_attr();
|
||||
break;
|
||||
default:
|
||||
|
@ -622,11 +624,10 @@ void end_element(svg_parser& parser, rapidxml::xml_node<char> const* node)
|
|||
}
|
||||
else if (name == "svg"_case)
|
||||
{
|
||||
parser.path_.end_group();
|
||||
if (node->first_node() != nullptr)
|
||||
{
|
||||
parser.path_.pop_attr();
|
||||
}
|
||||
//if (node->first_node() != nullptr)
|
||||
//{
|
||||
//parser.path_.pop_attr();
|
||||
//}
|
||||
}
|
||||
else if (name == "defs"_case)
|
||||
{
|
||||
|
@ -675,10 +676,10 @@ void parse_element(svg_parser& parser, char const* name, rapidxml::xml_node<char
|
|||
parse_ellipse(parser, node);
|
||||
break;
|
||||
case "svg"_case:
|
||||
parser.path_.begin_group();
|
||||
parser.path_.push_attr();
|
||||
//parser.path_.push_attr();
|
||||
parse_dimensions(parser, node);
|
||||
parse_attr(parser, node);
|
||||
parser.path_.set_opacity(parser.path_.cur_attr().opacity);
|
||||
break;
|
||||
default:
|
||||
handle_unsupported(parser, unsupported_elements, name, "element");
|
||||
|
|
Loading…
Reference in a new issue