summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
diff options
context:
space:
mode:
authorMacDue <macdue@dueutil.tech>2022-08-18 11:23:07 +0100
committerLinus Groh <mail@linusgroh.de>2022-09-03 16:57:37 +0100
commitf9b08272db411f807dd203bab025b5fccbe3f494 (patch)
treef6705bfa42ba4ddf6415409a11d1c1cb3ed1bb85 /Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
parent049c1a536c295cc85c0e3e42721cd3e4c382fe00 (diff)
downloadserenity-f9b08272db411f807dd203bab025b5fccbe3f494.zip
LibGfx: Add AntiAliasingPainter::fill_rect
This function is able to draw rectangles of floating-point pixel precision.
Diffstat (limited to 'Userland/Libraries/LibGfx/AntiAliasingPainter.cpp')
-rw-r--r--Userland/Libraries/LibGfx/AntiAliasingPainter.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
index 8f0aee5d6a..db42e46db4 100644
--- a/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
+++ b/Userland/Libraries/LibGfx/AntiAliasingPainter.cpp
@@ -238,6 +238,53 @@ void AntiAliasingPainter::draw_cubic_bezier_curve(FloatPoint const& control_poin
});
}
+void AntiAliasingPainter::fill_rect(FloatRect const& float_rect, Color color)
+{
+ // Draw the integer part of the rectangle:
+ float right_x = float_rect.x() + float_rect.width();
+ float bottom_y = float_rect.y() + float_rect.height();
+ int x1 = ceilf(float_rect.x());
+ int y1 = ceilf(float_rect.y());
+ int x2 = floorf(right_x);
+ int y2 = floorf(bottom_y);
+ auto solid_rect = Gfx::IntRect::from_two_points({ x1, y1 }, { x2, y2 });
+ m_underlying_painter.fill_rect(solid_rect, color);
+
+ if (float_rect == solid_rect)
+ return;
+
+ // Draw the rest:
+ float left_subpixel = x1 - float_rect.x();
+ float top_subpixel = y1 - float_rect.y();
+ float right_subpixel = right_x - x2;
+ float bottom_subpixel = bottom_y - y2;
+ float top_left_subpixel = top_subpixel * left_subpixel;
+ float top_right_subpixel = top_subpixel * right_subpixel;
+ float bottom_left_subpixel = bottom_subpixel * left_subpixel;
+ float bottom_right_subpixel = bottom_subpixel * right_subpixel;
+
+ auto subpixel = [&](float alpha) {
+ return color.with_alpha(color.alpha() * alpha);
+ };
+
+ auto set_pixel = [&](int x, int y, float alpha) {
+ m_underlying_painter.set_pixel(x, y, subpixel(alpha), true);
+ };
+
+ auto line_to_rect = [&](int x1, int y1, int x2, int y2) {
+ return IntRect::from_two_points({ x1, y1 }, { x2 + 1, y2 + 1 });
+ };
+
+ set_pixel(x1 - 1, y1 - 1, top_left_subpixel);
+ set_pixel(x2, y1 - 1, top_right_subpixel);
+ set_pixel(x2, y2, bottom_right_subpixel);
+ set_pixel(x1 - 1, y2, bottom_left_subpixel);
+ m_underlying_painter.fill_rect(line_to_rect(x1, y1 - 1, x2 - 1, y1 - 1), subpixel(top_subpixel));
+ m_underlying_painter.fill_rect(line_to_rect(x1, y2, x2 - 1, y2), subpixel(bottom_subpixel));
+ m_underlying_painter.fill_rect(line_to_rect(x1 - 1, y1, x1 - 1, y2 - 1), subpixel(left_subpixel));
+ m_underlying_painter.fill_rect(line_to_rect(x2, y1, x2, y2 - 1), subpixel(right_subpixel));
+}
+
void AntiAliasingPainter::draw_ellipse(IntRect const& a_rect, Color color, int thickness)
{
// FIXME: Come up with an allocation-free version of this!