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)
|
svg_height_(0.0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
void set_opacity(double opacity) { svg_group_.opacity = opacity; }
|
||||||
|
|
||||||
void begin_group()
|
void begin_group()
|
||||||
{
|
{
|
||||||
current_group_->elements.emplace_back(group {cur_attr().opacity, {}, current_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)
|
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)
|
for (auto const& elem : svg_group_.elements)
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(group_renderer<Rasterizer, Scanline, Renderer>
|
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,
|
group_renderer(renderer_agg& renderer,
|
||||||
Rasterizer & ras, Scanline& sl, Renderer& ren,
|
Rasterizer & ras, Scanline& sl, Renderer& ren,
|
||||||
agg::trans_affine const& mtx,
|
agg::trans_affine const& mtx,
|
||||||
double opacity,
|
box2d<double> const& symbol_bbox)
|
||||||
box2d<double> const& symbol_bbox,
|
|
||||||
bool first = false)
|
|
||||||
: renderer_(renderer),
|
: renderer_(renderer),
|
||||||
ras_(ras),
|
ras_(ras),
|
||||||
sl_(sl),
|
sl_(sl),
|
||||||
ren_(ren),
|
ren_(ren),
|
||||||
mtx_(mtx),
|
mtx_(mtx),
|
||||||
opacity_(opacity),
|
symbol_bbox_(symbol_bbox)
|
||||||
symbol_bbox_(symbol_bbox),
|
|
||||||
first_(first)
|
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void render_gradient(Rasterizer& ras,
|
void render_gradient(Rasterizer& ras,
|
||||||
|
@ -281,7 +294,6 @@ class renderer_agg : util::noncopyable
|
||||||
void operator() (group const& g) const
|
void operator() (group const& g) const
|
||||||
{
|
{
|
||||||
double opacity = g.opacity;
|
double opacity = g.opacity;
|
||||||
if (first_) opacity *= opacity_; // adjust top level opacity
|
|
||||||
if (opacity < 1.0)
|
if (opacity < 1.0)
|
||||||
{
|
{
|
||||||
mapnik::image_rgba8 im(ren_.width(), ren_.height(), true, true);
|
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)
|
for (auto const& elem : g.elements)
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(
|
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));
|
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)
|
for (auto const& elem : g.elements)
|
||||||
{
|
{
|
||||||
mapbox::util::apply_visitor(
|
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_;
|
Scanline& sl_;
|
||||||
Renderer& ren_;
|
Renderer& ren_;
|
||||||
agg::trans_affine const& mtx_;
|
agg::trans_affine const& mtx_;
|
||||||
double opacity_;
|
|
||||||
box2d<double> const& symbol_bbox_;
|
box2d<double> const& symbol_bbox_;
|
||||||
bool first_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(GRID_RENDERER)
|
#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_width = get_optional<double>(sym, keys::stroke_width, feature, vars);
|
||||||
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
|
auto stroke_opacity = get_optional<double>(sym, keys::stroke_opacity, feature, vars);
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
dst.opacity = src.opacity;
|
||||||
if (fill_color || fill_opacity || stroke_color || stroke_width || stroke_opacity)
|
if (fill_color || fill_opacity || stroke_color || stroke_width || stroke_opacity)
|
||||||
{
|
{
|
||||||
for (auto const& elem : src.elements)
|
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_)
|
if (parser.css_style_)
|
||||||
process_css(parser, node);
|
process_css(parser, node);
|
||||||
parse_attr(parser, node);
|
parse_attr(parser, node);
|
||||||
|
if (parser.path_.cur_attr().opacity < 1.0) parser.path_.begin_group();
|
||||||
parse_use(parser, node);
|
parse_use(parser, node);
|
||||||
|
if (parser.path_.cur_attr().opacity < 1.0) parser.path_.end_group();
|
||||||
parser.path_.pop_attr();
|
parser.path_.pop_attr();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -622,11 +624,10 @@ void end_element(svg_parser& parser, rapidxml::xml_node<char> const* node)
|
||||||
}
|
}
|
||||||
else if (name == "svg"_case)
|
else if (name == "svg"_case)
|
||||||
{
|
{
|
||||||
parser.path_.end_group();
|
//if (node->first_node() != nullptr)
|
||||||
if (node->first_node() != nullptr)
|
//{
|
||||||
{
|
//parser.path_.pop_attr();
|
||||||
parser.path_.pop_attr();
|
//}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (name == "defs"_case)
|
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);
|
parse_ellipse(parser, node);
|
||||||
break;
|
break;
|
||||||
case "svg"_case:
|
case "svg"_case:
|
||||||
parser.path_.begin_group();
|
//parser.path_.push_attr();
|
||||||
parser.path_.push_attr();
|
|
||||||
parse_dimensions(parser, node);
|
parse_dimensions(parser, node);
|
||||||
parse_attr(parser, node);
|
parse_attr(parser, node);
|
||||||
|
parser.path_.set_opacity(parser.path_.cur_attr().opacity);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
handle_unsupported(parser, unsupported_elements, name, "element");
|
handle_unsupported(parser, unsupported_elements, name, "element");
|
||||||
|
|
Loading…
Reference in a new issue