diff options
author | Ali Mohammad Pur <ali.mpfard@gmail.com> | 2021-09-17 12:03:24 +0430 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-09-18 02:12:38 +0430 |
commit | 5a2e7d30ce2f673cd84073c1e96287329fe310db (patch) | |
tree | 897b0f223a76a5a0fe462b8eed152e8ab527e470 | |
parent | e2cd5581018601c0efd248e764dfd8546be70d60 (diff) | |
download | serenity-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.cpp | 25 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/AntiAliasingPainter.h | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/FillPathImplementation.h | 12 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/SVGPathBox.cpp | 5 |
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); |