1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 14:07:45 +00:00

LibGfx: Add AntiAliasingPainter::fill_rect

This function is able to draw rectangles of floating-point pixel
precision.
This commit is contained in:
MacDue 2022-08-18 11:23:07 +01:00 committed by Linus Groh
parent 049c1a536c
commit f9b08272db
2 changed files with 49 additions and 0 deletions

View file

@ -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) void AntiAliasingPainter::draw_ellipse(IntRect const& a_rect, Color color, int thickness)
{ {
// FIXME: Come up with an allocation-free version of this! // FIXME: Come up with an allocation-free version of this!

View file

@ -35,6 +35,8 @@ public:
AlphaSubtract AlphaSubtract
}; };
void fill_rect(FloatRect const&, Color);
void fill_circle(IntPoint const& center, int radius, Color, BlendMode blend_mode = BlendMode::Normal); void fill_circle(IntPoint const& center, int radius, Color, BlendMode blend_mode = BlendMode::Normal);
void fill_ellipse(IntRect const& a_rect, Color, BlendMode blend_mode = BlendMode::Normal); void fill_ellipse(IntRect const& a_rect, Color, BlendMode blend_mode = BlendMode::Normal);