summaryrefslogtreecommitdiff
path: root/Userland/Services
diff options
context:
space:
mode:
authorTom <tomut@yahoo.com>2021-06-25 09:09:41 -0600
committerAndreas Kling <kling@serenityos.org>2021-06-25 20:38:13 +0200
commit42cb38b71a469c5b68280f9bc4b54a895781159d (patch)
treeed2bf0eb74e3c6b77113a44dc65482212c0c0ada /Userland/Services
parentb9ad6058aa05b723c51beac35184ab29f7cbc113 (diff)
downloadserenity-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.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&);