summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2023-06-03 23:40:03 +0100
committerAndreas Kling <kling@serenityos.org>2023-06-04 05:40:39 +0200
commit6abc51d9f80892feef201bda6194bf5beaa7092f (patch)
tree3107bb7aa456de1ab7452daecb9d88c10ef31af3
parent910bff9e94ee9c304b61d342f23a4962e51a05af (diff)
downloadserenity-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.cpp8
-rw-r--r--Userland/Libraries/LibGfx/Font/PathRasterizer.cpp2
-rw-r--r--Userland/Libraries/LibGfx/Path.cpp47
-rw-r--r--Userland/Libraries/LibGfx/Path.h13
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;
};