1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-15 10:04:59 +00:00
serenity/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp
Andreas Kling 0ba2a3ff30 LibWeb: Don't fill or stroke SVG <path> with transparent color
Before this, we were filling and stroking every <path>, whether they had
a fill/stroke color or not. We can avoid a bunch of unnecessary work by
checking if the color is transparent (also the case if unset) before
doing the painting work.

If there is no fill color, we also avoid making a copy of the path to
ensure that it's closed.
2022-02-09 13:44:00 +01:00

62 lines
1.9 KiB
C++

/*
* Copyright (c) 2020, Matthew Olsson <matthewcolsson@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibGfx/AntiAliasingPainter.h>
#include <LibGfx/Painter.h>
#include <LibWeb/Layout/SVGPathBox.h>
#include <LibWeb/SVG/SVGPathElement.h>
namespace Web::Layout {
SVGPathBox::SVGPathBox(DOM::Document& document, SVG::SVGPathElement& element, NonnullRefPtr<CSS::StyleProperties> properties)
: SVGGraphicsBox(document, element, properties)
{
}
void SVGPathBox::paint(PaintContext& context, PaintPhase phase)
{
if (!is_visible())
return;
SVGGraphicsBox::paint(context, phase);
if (phase != PaintPhase::Foreground)
return;
auto& path_element = dom_node();
auto& path = path_element.get_path();
Gfx::AntiAliasingPainter painter { context.painter() };
auto& svg_context = context.svg_context();
auto offset = absolute_position();
painter.translate(offset);
if (auto fill_color = path_element.fill_color().value_or(svg_context.fill_color()); fill_color.alpha() > 0) {
// We need to fill the path before applying the stroke, however the filled
// path must be closed, whereas the stroke path may not necessary be closed.
// Copy the path and close it for filling, but use the previous path for stroke
auto closed_path = path;
closed_path.close();
// Fills are computed as though all paths are closed (https://svgwg.org/svg2-draft/painting.html#FillProperties)
painter.fill_path(
closed_path,
fill_color,
Gfx::Painter::WindingRule::EvenOdd);
}
if (auto stroke_color = path_element.stroke_color().value_or(svg_context.stroke_color()); stroke_color.alpha() > 0) {
painter.stroke_path(
path,
stroke_color,
path_element.stroke_width().value_or(svg_context.stroke_width()));
}
painter.translate(-offset);
}
}