mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 11:57:35 +00:00
LibGfx: Support AlphaSubtract blend mode for AA rounded rectangle
This commit is contained in:
parent
0805911a93
commit
c1798620d9
2 changed files with 23 additions and 11 deletions
|
@ -445,10 +445,14 @@ void Gfx::AntiAliasingPainter::fill_rect_with_rounded_corners(IntRect const& a_r
|
||||||
{ bottom_left_radius, bottom_left_radius });
|
{ bottom_left_radius, bottom_left_radius });
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx::AntiAliasingPainter::fill_rect_with_rounded_corners(IntRect const& a_rect, Color color, CornerRadius top_left, CornerRadius top_right, CornerRadius bottom_right, CornerRadius bottom_left)
|
void Gfx::AntiAliasingPainter::fill_rect_with_rounded_corners(IntRect const& a_rect, Color color, CornerRadius top_left, CornerRadius top_right, CornerRadius bottom_right, CornerRadius bottom_left, BlendMode blend_mode)
|
||||||
{
|
{
|
||||||
if (!top_left && !top_right && !bottom_right && !bottom_left)
|
if (!top_left && !top_right && !bottom_right && !bottom_left) {
|
||||||
|
if (blend_mode == BlendMode::Normal)
|
||||||
return m_underlying_painter.fill_rect(a_rect, color);
|
return m_underlying_painter.fill_rect(a_rect, color);
|
||||||
|
else if (blend_mode == BlendMode::AlphaSubtract)
|
||||||
|
return m_underlying_painter.clear_rect(a_rect, Color());
|
||||||
|
}
|
||||||
|
|
||||||
if (color.alpha() == 0)
|
if (color.alpha() == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -472,7 +476,7 @@ void Gfx::AntiAliasingPainter::fill_rect_with_rounded_corners(IntRect const& a_r
|
||||||
|
|
||||||
// All corners are centered at the same point, so this can be painted as a single ellipse.
|
// All corners are centered at the same point, so this can be painted as a single ellipse.
|
||||||
if (top_left_corner == top_right_corner && top_right_corner == bottom_left_corner && bottom_left_corner == bottom_right_corner)
|
if (top_left_corner == top_right_corner && top_right_corner == bottom_left_corner && bottom_left_corner == bottom_right_corner)
|
||||||
return fill_ellipse(a_rect, color);
|
return fill_ellipse(a_rect, color, blend_mode);
|
||||||
|
|
||||||
IntRect top_rect {
|
IntRect top_rect {
|
||||||
a_rect.x() + top_left.horizontal_radius,
|
a_rect.x() + top_left.horizontal_radius,
|
||||||
|
@ -506,16 +510,24 @@ void Gfx::AntiAliasingPainter::fill_rect_with_rounded_corners(IntRect const& a_r
|
||||||
a_rect.height() - top_rect.height() - bottom_rect.height()
|
a_rect.height() - top_rect.height() - bottom_rect.height()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (blend_mode == BlendMode::Normal) {
|
||||||
m_underlying_painter.fill_rect(top_rect, color);
|
m_underlying_painter.fill_rect(top_rect, color);
|
||||||
m_underlying_painter.fill_rect(right_rect, color);
|
m_underlying_painter.fill_rect(right_rect, color);
|
||||||
m_underlying_painter.fill_rect(bottom_rect, color);
|
m_underlying_painter.fill_rect(bottom_rect, color);
|
||||||
m_underlying_painter.fill_rect(left_rect, color);
|
m_underlying_painter.fill_rect(left_rect, color);
|
||||||
m_underlying_painter.fill_rect(inner, color);
|
m_underlying_painter.fill_rect(inner, color);
|
||||||
|
} else if (blend_mode == BlendMode::AlphaSubtract) {
|
||||||
|
m_underlying_painter.clear_rect(top_rect, Gfx::Color());
|
||||||
|
m_underlying_painter.clear_rect(right_rect, Gfx::Color());
|
||||||
|
m_underlying_painter.clear_rect(bottom_rect, Gfx::Color());
|
||||||
|
m_underlying_painter.clear_rect(left_rect, Gfx::Color());
|
||||||
|
m_underlying_painter.clear_rect(inner, Gfx::Color());
|
||||||
|
}
|
||||||
|
|
||||||
auto fill_corner = [&](auto const& ellipse_center, auto const& corner_point, CornerRadius const& corner) {
|
auto fill_corner = [&](auto const& ellipse_center, auto const& corner_point, CornerRadius const& corner) {
|
||||||
PainterStateSaver save { m_underlying_painter };
|
PainterStateSaver save { m_underlying_painter };
|
||||||
m_underlying_painter.add_clip_rect(IntRect::from_two_points(ellipse_center, corner_point));
|
m_underlying_painter.add_clip_rect(IntRect::from_two_points(ellipse_center, corner_point));
|
||||||
fill_ellipse(IntRect::centered_at(ellipse_center, { corner.horizontal_radius * 2, corner.vertical_radius * 2 }), color);
|
fill_ellipse(IntRect::centered_at(ellipse_center, { corner.horizontal_radius * 2, corner.vertical_radius * 2 }), color, blend_mode);
|
||||||
};
|
};
|
||||||
|
|
||||||
auto bounding_rect = a_rect.inflated(0, 1, 1, 0);
|
auto bounding_rect = a_rect.inflated(0, 1, 1, 0);
|
||||||
|
|
|
@ -51,7 +51,7 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void fill_rect_with_rounded_corners(IntRect const&, Color, CornerRadius top_left, CornerRadius top_right, CornerRadius bottom_right, CornerRadius bottom_left);
|
void fill_rect_with_rounded_corners(IntRect const&, Color, CornerRadius top_left, CornerRadius top_right, CornerRadius bottom_right, CornerRadius bottom_left, BlendMode blend_mode = BlendMode::Normal);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct Range {
|
struct Range {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue