diff options
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.cpp | 28 | ||||
-rw-r--r-- | Userland/Services/WindowServer/WindowFrame.h | 3 |
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&); |