diff options
author | Tom <tomut@yahoo.com> | 2021-06-25 09:09:41 -0600 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-06-25 20:38:13 +0200 |
commit | 42cb38b71a469c5b68280f9bc4b54a895781159d (patch) | |
tree | ed2bf0eb74e3c6b77113a44dc65482212c0c0ada /Userland/Services | |
parent | b9ad6058aa05b723c51beac35184ab29f7cbc113 (diff) | |
download | serenity-42cb38b71a469c5b68280f9bc4b54a895781159d.zip |
WindowServer: Enhance simple shadow function to include optional frame
If the shadow bitmap contains portions of the frame then we need to
slightly tweak the logic dealing with very small width and/or height.
Diffstat (limited to 'Userland/Services')
-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&); |