summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-17 12:03:24 +0430
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-09-18 02:12:38 +0430
commit5a2e7d30ce2f673cd84073c1e96287329fe310db (patch)
tree897b0f223a76a5a0fe462b8eed152e8ab527e470
parente2cd5581018601c0efd248e764dfd8546be70d60 (diff)
downloadserenity-5a2e7d30ce2f673cd84073c1e96287329fe310db.zip
LibWeb: Use Gfx::AntiAliasingPainter to draw SVG paths
This is still quite bad, but it's much more pleasing to look at when drawing random SVGs :^)
-rw-r--r--Userland/Libraries/LibGfx/AntiAliasingPainter.cpp25
-rw-r--r--Userland/Libraries/LibGfx/AntiAliasingPainter.h8
-rw-r--r--Userland/Libraries/LibGfx/FillPathImplementation.h12
-rw-r--r--Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp5
4 files changed, 42 insertions, 8 deletions
diff --git a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
index a4de8c75db..8d95a50c64 100644
--- a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
+++ b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
@@ -16,7 +16,8 @@ static float fractional_part(float x)
// Base algorithm from https://en.wikipedia.org/wiki/Xiaolin_Wu%27s_line_algorithm,
// because there seems to be no other known method for drawing AA'd lines (?)
-void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color)
+template<Gfx::AntiAliasingPainter::AntiAliasPolicy policy>
+void Gfx::AntiAliasingPainter::draw_anti_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color)
{
// FIXME: Implement this :P
VERIFY(style == Painter::LineStyle::Solid);
@@ -76,10 +77,18 @@ void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoi
auto x = first_end_point.x();
while (x < last_end_point.x()) {
if (is_steep) {
- draw_point({ floorf(next_intersection), x }, color_with_alpha(1 - fractional_part(next_intersection)));
+ if constexpr (policy == AntiAliasPolicy::OnlyEnds) {
+ draw_point({ floorf(next_intersection), x }, color);
+ } else {
+ draw_point({ floorf(next_intersection), x }, color_with_alpha(1 - fractional_part(next_intersection)));
+ }
draw_point({ floorf(next_intersection) + 1, x }, color_with_alpha(fractional_part(next_intersection)));
} else {
- draw_point({ x, floorf(next_intersection) }, color_with_alpha(1 - fractional_part(next_intersection)));
+ if constexpr (policy == AntiAliasPolicy::OnlyEnds) {
+ draw_point({ x, floorf(next_intersection) }, color);
+ } else {
+ draw_point({ x, floorf(next_intersection) }, color_with_alpha(1 - fractional_part(next_intersection)));
+ }
draw_point({ x, floorf(next_intersection) + 1 }, color_with_alpha(fractional_part(next_intersection)));
}
next_intersection += delta_y;
@@ -87,6 +96,16 @@ void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoi
}
}
+void Gfx::AntiAliasingPainter::draw_aliased_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
+{
+ draw_anti_aliased_line<AntiAliasPolicy::OnlyEnds>(actual_from, actual_to, color, thickness, style, alternate_color);
+}
+
+void Gfx::AntiAliasingPainter::draw_line(FloatPoint const& actual_from, FloatPoint const& actual_to, Color color, float thickness, Gfx::Painter::LineStyle style, Color alternate_color)
+{
+ draw_anti_aliased_line<AntiAliasPolicy::Full>(actual_from, actual_to, color, thickness, style, alternate_color);
+}
+
void Gfx::AntiAliasingPainter::fill_path(Path& path, Color color, Painter::WindingRule rule)
{
Detail::fill_path<Detail::FillPathMode::AllowFloatingPoints>(*this, path, color, rule);
diff --git a/Userland/Libraries/LibGfx/AntiAliasingPainter.h b/Userland/Libraries/LibGfx/AntiAliasingPainter.h
index 68b504b507..64a3a17a53 100644
--- a/Userland/Libraries/LibGfx/AntiAliasingPainter.h
+++ b/Userland/Libraries/LibGfx/AntiAliasingPainter.h
@@ -18,6 +18,7 @@ public:
}
void draw_line(FloatPoint const&, FloatPoint const&, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid, Color alternate_color = Color::Transparent);
+ void draw_aliased_line(FloatPoint const&, FloatPoint const&, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid, Color alternate_color = Color::Transparent);
void fill_path(Path&, Color, Painter::WindingRule rule = Painter::WindingRule::Nonzero);
void stroke_path(Path const&, Color, float thickness);
void draw_quadratic_bezier_curve(FloatPoint const& control_point, FloatPoint const&, FloatPoint const&, Color, float thickness = 1, Painter::LineStyle style = Painter::LineStyle::Solid);
@@ -27,6 +28,13 @@ public:
void translate(FloatPoint const& delta) { m_transform.translate(delta); }
private:
+ enum class AntiAliasPolicy {
+ OnlyEnds,
+ Full,
+ };
+ template<AntiAliasPolicy policy>
+ void draw_anti_aliased_line(FloatPoint const&, FloatPoint const&, Color, float thickness, Painter::LineStyle style, Color alternate_color);
+
Painter& m_underlying_painter;
AffineTransform m_transform;
};
diff --git a/Userland/Libraries/LibGfx/FillPathImplementation.h b/Userland/Libraries/LibGfx/FillPathImplementation.h
index c2ab76fd0f..192ff85745 100644
--- a/Userland/Libraries/LibGfx/FillPathImplementation.h
+++ b/Userland/Libraries/LibGfx/FillPathImplementation.h
@@ -46,6 +46,12 @@ void fill_path(Painter& painter, Path const& path, Color color, Gfx::Painter::Wi
{
using GridCoordinateType = Conditional<fill_path_mode == FillPathMode::PlaceOnIntGrid, int, float>;
using PointType = Point<GridCoordinateType>;
+ auto draw_line = [&](auto... args) {
+ if constexpr (requires { painter.draw_aliased_line(args...); })
+ painter.draw_aliased_line(args...);
+ else
+ painter.draw_line(args...);
+ };
auto const& segments = path.split_lines();
@@ -130,7 +136,7 @@ void fill_path(Painter& painter, Path const& path, Color color, Gfx::Painter::Wi
// inside the shape
dbgln_if(FILL_PATH_DEBUG, "y={}: {} at {}: {} -- {}", scanline, winding_number, i, from, to);
- painter.draw_line(from, to, color, 1);
+ draw_line(from, to, color, 1);
}
auto is_passing_through_maxima = scanline == previous.maximum_y
@@ -153,7 +159,7 @@ void fill_path(Painter& painter, Path const& path, Color color, Gfx::Painter::Wi
active_list.last().x -= active_list.last().inverse_slope;
} else {
auto point = PointType(active_list[0].x, scanline);
- painter.draw_line(point, point, color);
+ draw_line(point, point, color);
// update the x coord
active_list.first().x -= active_list.first().inverse_slope;
@@ -183,7 +189,7 @@ void fill_path(Painter& painter, Path const& path, Color color, Gfx::Painter::Wi
if constexpr (FILL_PATH_DEBUG) {
size_t i { 0 };
for (auto& segment : segments) {
- painter.draw_line(PointType(segment.from), PointType(segment.to), Color::from_hsv(i++ * 360.0 / segments.size(), 1.0, 1.0), 1);
+ draw_line(PointType(segment.from), PointType(segment.to), Color::from_hsv(i++ * 360.0 / segments.size(), 1.0, 1.0), 1);
}
}
}
diff --git a/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp b/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp
index a7377c069c..b93a05c90d 100644
--- a/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp
+++ b/Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: BSD-2-Clause
*/
+#include <LibGfx/AntiAliasingPainter.h>
#include <LibGfx/Painter.h>
#include <LibWeb/Layout/SVGPathBox.h>
#include <LibWeb/SVG/SVGPathElement.h>
@@ -47,10 +48,10 @@ void SVGPathBox::paint(PaintContext& context, PaintPhase phase)
closed_path.close();
// Fills are computed as though all paths are closed (https://svgwg.org/svg2-draft/painting.html#FillProperties)
- auto& painter = context.painter();
+ Gfx::AntiAliasingPainter painter { context.painter() };
auto& svg_context = context.svg_context();
- auto offset = (absolute_position() - effective_offset()).to_type<int>();
+ auto offset = absolute_position() - effective_offset();
painter.translate(offset);