diff options
author | MacDue <macdue@dueutil.tech> | 2023-06-03 23:40:03 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2023-06-04 05:40:39 +0200 |
commit | 6abc51d9f80892feef201bda6194bf5beaa7092f (patch) | |
tree | 3107bb7aa456de1ab7452daecb9d88c10ef31af3 | |
parent | 910bff9e94ee9c304b61d342f23a4962e51a05af (diff) | |
download | serenity-6abc51d9f80892feef201bda6194bf5beaa7092f.zip |
LibGfx: Simplify segmentizing paths
Remove SplitLineSegment and replace it with a FloatLine, nobody was
interested in its extra fields anymore. Also, remove the sorting of
the split segments, this really should not have been done here
anyway, and is not required by the rasterizer anymore. Keeping the
segments in stroke order will also make it possible to generate
stroked path geometry (in future).
-rw-r--r-- | Userland/Libraries/LibGfx/EdgeFlagPathRasterizer.cpp | 8 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Font/PathRasterizer.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Path.cpp | 47 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Path.h | 13 |
4 files changed, 21 insertions, 49 deletions
diff --git a/Userland/Libraries/LibGfx/EdgeFlagPathRasterizer.cpp b/Userland/Libraries/LibGfx/EdgeFlagPathRasterizer.cpp index 488e469f82..cb0fd5f2ce 100644 --- a/Userland/Libraries/LibGfx/EdgeFlagPathRasterizer.cpp +++ b/Userland/Libraries/LibGfx/EdgeFlagPathRasterizer.cpp @@ -30,15 +30,13 @@ namespace Gfx { -static Vector<Detail::Edge> prepare_edges(ReadonlySpan<Path::SplitLineSegment> lines, unsigned samples_per_pixel, FloatPoint origin) +static Vector<Detail::Edge> prepare_edges(ReadonlySpan<FloatLine> lines, unsigned samples_per_pixel, FloatPoint origin) { - // FIXME: split_lines() gives similar information, but the form it's in is not that useful (and is const anyway). Vector<Detail::Edge> edges; edges.ensure_capacity(lines.size()); - for (auto& line : lines) { - auto p0 = line.from - origin; - auto p1 = line.to - origin; + auto p0 = line.a() - origin; + auto p1 = line.b() - origin; p0.scale_by(1, samples_per_pixel); p1.scale_by(1, samples_per_pixel); diff --git a/Userland/Libraries/LibGfx/Font/PathRasterizer.cpp b/Userland/Libraries/LibGfx/Font/PathRasterizer.cpp index 51b4c1032f..420e77be0a 100644 --- a/Userland/Libraries/LibGfx/Font/PathRasterizer.cpp +++ b/Userland/Libraries/LibGfx/Font/PathRasterizer.cpp @@ -20,7 +20,7 @@ PathRasterizer::PathRasterizer(Gfx::IntSize size) void PathRasterizer::draw_path(Gfx::Path& path) { for (auto& line : path.split_lines()) - draw_line(line.from, line.to); + draw_line(line.a(), line.b()); } RefPtr<Gfx::Bitmap> PathRasterizer::accumulate() diff --git a/Userland/Libraries/LibGfx/Path.cpp b/Userland/Libraries/LibGfx/Path.cpp index a7e94a6376..ed94af9cb9 100644 --- a/Userland/Libraries/LibGfx/Path.cpp +++ b/Userland/Libraries/LibGfx/Path.cpp @@ -239,52 +239,38 @@ DeprecatedString Path::to_deprecated_string() const void Path::segmentize_path() { - Vector<SplitLineSegment> segments; + Vector<FloatLine> segments; float min_x = 0; float min_y = 0; float max_x = 0; float max_y = 0; + bool first = true; auto add_point_to_bbox = [&](Gfx::FloatPoint point) { float x = point.x(); float y = point.y(); - min_x = min(min_x, x); - min_y = min(min_y, y); - max_x = max(max_x, x); - max_y = max(max_y, y); + if (first) { + min_x = max_x = x; + min_y = max_y = y; + first = false; + } else { + min_x = min(min_x, x); + min_y = min(min_y, y); + max_x = max(max_x, x); + max_y = max(max_y, y); + } }; auto add_line = [&](auto const& p0, auto const& p1) { - float ymax = p0.y(), ymin = p1.y(), x_of_ymin = p1.x(), x_of_ymax = p0.x(); - auto slope = p0.x() == p1.x() ? 0 : ((float)(p0.y() - p1.y())) / ((float)(p0.x() - p1.x())); - if (p0.y() < p1.y()) { - swap(ymin, ymax); - swap(x_of_ymin, x_of_ymax); - } - - segments.append({ FloatPoint(p0.x(), p0.y()), - FloatPoint(p1.x(), p1.y()), - slope == 0 ? 0 : 1 / slope, - x_of_ymin, - ymax, ymin, x_of_ymax }); - + segments.append({ p0, p1 }); add_point_to_bbox(p1); }; FloatPoint cursor { 0, 0 }; - bool first = true; - for (auto& segment : m_segments) { switch (segment->type()) { case Segment::Type::MoveTo: - if (first) { - min_x = segment->point().x(); - min_y = segment->point().y(); - max_x = segment->point().x(); - max_y = segment->point().y(); - } else { - add_point_to_bbox(segment->point()); - } + add_point_to_bbox(segment->point()); cursor = segment->point(); break; case Segment::Type::LineTo: { @@ -325,11 +311,6 @@ void Path::segmentize_path() first = false; } - // sort segments by ymax - quick_sort(segments, [](auto const& line0, auto const& line1) { - return line1.maximum_y < line0.maximum_y; - }); - m_split_lines = move(segments); m_bounding_box = Gfx::FloatRect { min_x, min_y, max_x - min_x, max_y - min_y }; } diff --git a/Userland/Libraries/LibGfx/Path.h b/Userland/Libraries/LibGfx/Path.h index f2d6c05f38..6c31c02e19 100644 --- a/Userland/Libraries/LibGfx/Path.h +++ b/Userland/Libraries/LibGfx/Path.h @@ -11,6 +11,7 @@ #include <AK/Optional.h> #include <AK/Vector.h> #include <LibGfx/Forward.h> +#include <LibGfx/Line.h> #include <LibGfx/Point.h> #include <LibGfx/Rect.h> @@ -208,16 +209,8 @@ public: void close(); void close_all_subpaths(); - struct SplitLineSegment { - FloatPoint from, to; - float inverse_slope; - float x_of_minimum_y; - float maximum_y; - float minimum_y; - float x; - }; - Vector<NonnullRefPtr<Segment const>> const& segments() const { return m_segments; } + auto& split_lines() const { if (!m_split_lines.has_value()) { @@ -270,7 +263,7 @@ private: Vector<NonnullRefPtr<Segment const>> m_segments {}; - Optional<Vector<SplitLineSegment>> m_split_lines {}; + Optional<Vector<FloatLine>> m_split_lines {}; Optional<Gfx::FloatRect> m_bounding_box; }; |