summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Services/WindowServer/WindowFrame.cpp28
-rw-r--r--Userland/Services/WindowServer/WindowFrame.h3
2 files changed, 21 insertions, 10 deletions
diff --git a/Userland/Services/WindowServer/WindowFrame.cpp b/Userland/Services/WindowServer/WindowFrame.cpp
index e237d5c8f5..eea1317e7b 100644
--- a/Userland/Services/WindowServer/WindowFrame.cpp
+++ b/Userland/Services/WindowServer/WindowFrame.cpp
@@ -884,7 +884,7 @@ void WindowFrame::start_flash_animation()
m_flash_timer->start();
}
-void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::IntRect& containing_rect, const Gfx::Bitmap& shadow_bitmap) const
+void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::IntRect& containing_rect, const Gfx::Bitmap& shadow_bitmap, bool shadow_includes_frame, bool fill_content)
{
// The layout of the shadow_bitmap is defined like this:
// +---------+----+---------+----+----+----+
@@ -902,6 +902,7 @@ void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::Int
// The height divided by two defines a cell size, and width of each
// column must be the same as the height of the cell, except for the
// first an third column, which are twice as wide.
+ // If fill_content is true, it will use the RGBA color of right-bottom pixel of TL to fill the rectangle enclosed
if (shadow_bitmap.height() % 2 != 0) {
dbgln("Can't paint simple rect shadow, shadow bitmap height {} is not even", shadow_bitmap.height());
return;
@@ -923,21 +924,21 @@ void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::Int
auto containing_horizontal_rect = containing_rect;
int horizontal_shift = 0;
- if (half_height < base_size) {
- // If the height is too small we need to shift the left/right accordingly
+ if (half_height < base_size && !shadow_includes_frame) {
+ // If the height is too small we need to shift the left/right accordingly, unless the shadow includes portions of the frame
horizontal_shift = base_size - half_height;
containing_horizontal_rect.set_left(containing_horizontal_rect.left() + horizontal_shift);
containing_horizontal_rect.set_right(containing_horizontal_rect.right() - 2 * horizontal_shift);
}
auto half_width = containing_horizontal_rect.width() / 2;
+ int corner_piece_width = min(containing_horizontal_rect.width() / 2, base_size * 2);
+ int left_corners_right = containing_horizontal_rect.left() + corner_piece_width;
+ int right_corners_left = max(containing_horizontal_rect.right() - corner_piece_width + 1, left_corners_right + 1);
auto paint_horizontal = [&](int y, int src_row) {
if (half_width <= 0)
return;
Gfx::PainterStateSaver save(painter);
painter.add_clip_rect({ containing_horizontal_rect.left(), y, containing_horizontal_rect.width(), base_size });
- int corner_piece_width = min(containing_horizontal_rect.width() / 2, base_size * 2);
- int left_corners_right = containing_horizontal_rect.left() + corner_piece_width;
- int right_corners_left = max(containing_horizontal_rect.right() - corner_piece_width + 1, left_corners_right + 1);
painter.blit({ containing_horizontal_rect.left(), y }, shadow_bitmap, { 0, src_row * base_size, corner_piece_width, base_size });
painter.blit({ right_corners_left, y }, shadow_bitmap, { 5 * base_size - corner_piece_width, src_row * base_size, corner_piece_width, base_size });
for (int x = left_corners_right; x < right_corners_left; x += base_size) {
@@ -949,12 +950,12 @@ void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::Int
paint_horizontal(containing_rect.top(), 0);
paint_horizontal(containing_rect.bottom() - base_size + 1, 1);
+ int corner_piece_height = min(half_height, base_size);
+ int top_corners_bottom = base_size + corner_piece_height;
+ int bottom_corners_top = base_size + max(half_height, sides_height - corner_piece_height);
auto paint_vertical = [&](int x, int src_row, int hshift, int hsrcshift) {
Gfx::PainterStateSaver save(painter);
painter.add_clip_rect({ x, containing_rect.y() + base_size, base_size, containing_rect.height() - 2 * base_size });
- int corner_piece_height = min(half_height, base_size);
- int top_corners_bottom = base_size + corner_piece_height;
- int bottom_corners_top = base_size + max(half_height, sides_height - corner_piece_height);
painter.blit({ x + hshift, containing_rect.top() + top_corners_bottom - corner_piece_height }, shadow_bitmap, { base_size * 5 + hsrcshift, src_row * base_size, base_size - hsrcshift, corner_piece_height });
painter.blit({ x + hshift, containing_rect.top() + bottom_corners_top }, shadow_bitmap, { base_size * 7 + hsrcshift, src_row * base_size + base_size - corner_piece_height, base_size - hsrcshift, corner_piece_height });
for (int y = top_corners_bottom; y < bottom_corners_top; y += base_size) {
@@ -964,7 +965,16 @@ void WindowFrame::paint_simple_rect_shadow(Gfx::Painter& painter, const Gfx::Int
};
paint_vertical(containing_rect.left(), 0, horizontal_shift, 0);
+ if (shadow_includes_frame)
+ horizontal_shift = 0; // TODO: fix off-by-one on rectangles barely wide enough
paint_vertical(containing_rect.right() - base_size + 1, 1, 0, horizontal_shift);
+
+ if (fill_content) {
+ // Fill the enclosed rectangle with the RGBA color of the right-bottom pixel of the TL tile
+ auto inner_rect = containing_rect.shrunken(2 * base_size, 2 * base_size);
+ if (!inner_rect.is_empty())
+ painter.fill_rect(inner_rect, shadow_bitmap.get_pixel(2 * base_size - 1, base_size - 1));
+ }
}
int WindowFrame::menu_row_count() const
diff --git a/Userland/Services/WindowServer/WindowFrame.h b/Userland/Services/WindowServer/WindowFrame.h
index 4ee4def28d..03ed6ecb01 100644
--- a/Userland/Services/WindowServer/WindowFrame.h
+++ b/Userland/Services/WindowServer/WindowFrame.h
@@ -118,8 +118,9 @@ public:
void open_menubar_menu(Menu&);
+ static void paint_simple_rect_shadow(Gfx::Painter&, const Gfx::IntRect&, const Gfx::Bitmap&, bool shadow_includes_frame = false, bool fill_content = false);
+
private:
- void paint_simple_rect_shadow(Gfx::Painter&, const Gfx::IntRect&, const Gfx::Bitmap&) const;
void paint_notification_frame(Gfx::Painter&);
void paint_normal_frame(Gfx::Painter&);
void paint_tool_window_frame(Gfx::Painter&);