diff options
author | Mihai Parparita <mihai@persistent.info> | 2021-03-05 16:42:50 -0800 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-06 14:56:31 +0100 |
commit | c2f3d3afe1263a280ab8901f15e369c90680b28c (patch) | |
tree | 8086749b3b394efb4bd8cc274b7dff5aabf2608b /Userland | |
parent | e97865e9828655fdb7e7ead4f1fd7743a884c609 (diff) | |
download | serenity-c2f3d3afe1263a280ab8901f15e369c90680b28c.zip |
LibWeb: Make CSS background image painting respect destination origin and transparency
It was previously using draw_tiled_bitmap, which always aligns the
tiles with the global origin and does not respect the alpha of the
source. Switch to a new Painter::blit_tiled helper which uses
Painter::blit under the hood, which has more correct behavior.
Diffstat (limited to 'Userland')
-rw-r--r-- | Userland/Libraries/LibGfx/Painter.cpp | 22 | ||||
-rw-r--r-- | Userland/Libraries/LibGfx/Painter.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Box.cpp | 9 |
3 files changed, 28 insertions, 4 deletions
diff --git a/Userland/Libraries/LibGfx/Painter.cpp b/Userland/Libraries/LibGfx/Painter.cpp index 445f4eda35..021648a1f2 100644 --- a/Userland/Libraries/LibGfx/Painter.cpp +++ b/Userland/Libraries/LibGfx/Painter.cpp @@ -1726,4 +1726,26 @@ void Painter::blit_disabled(const IntPoint& location, const Gfx::Bitmap& bitmap, }); } +void Painter::blit_tiled(const IntRect& dst_rect, const Gfx::Bitmap& bitmap, const IntRect& rect) +{ + auto tile_width = rect.width(); + auto tile_height = rect.height(); + auto dst_right = dst_rect.right(); + auto dst_bottom = dst_rect.bottom(); + for (int tile_y = dst_rect.top(); tile_y < dst_bottom; tile_y += tile_height) { + for (int tile_x = dst_rect.left(); tile_x < dst_right; tile_x += tile_width) { + IntRect tile_src_rect = rect; + auto tile_x_overflow = tile_x + tile_width - dst_right; + if (tile_x_overflow > 0) { + tile_src_rect.set_width(tile_width - tile_x_overflow); + } + auto tile_y_overflow = tile_y + tile_height - dst_bottom; + if (tile_y_overflow > 0) { + tile_src_rect.set_height(tile_height - tile_y_overflow); + } + blit(IntPoint(tile_x, tile_y), bitmap, tile_src_rect); + } + } +} + } diff --git a/Userland/Libraries/LibGfx/Painter.h b/Userland/Libraries/LibGfx/Painter.h index 8238fe599e..b7b6d003d7 100644 --- a/Userland/Libraries/LibGfx/Painter.h +++ b/Userland/Libraries/LibGfx/Painter.h @@ -77,6 +77,7 @@ public: void draw_tiled_bitmap(const IntRect& dst_rect, const Gfx::Bitmap&); void blit_offset(const IntPoint&, const Gfx::Bitmap&, const IntRect& src_rect, const IntPoint&); void blit_disabled(const IntPoint&, const Gfx::Bitmap&, const IntRect&, const Palette&); + void blit_tiled(const IntRect&, const Gfx::Bitmap&, const IntRect& src_rect); void draw_text(const IntRect&, const StringView&, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None); void draw_text(const IntRect&, const StringView&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None); void draw_text(const IntRect&, const Utf32View&, const Font&, TextAlignment = TextAlignment::TopLeft, Color = Color::Black, TextElision = TextElision::None); diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index 0cea9f0b3f..dd466a371a 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -46,10 +46,11 @@ void Box::paint(PaintContext& context, PaintPhase phase) auto padded_rect = this->padded_rect(); if (phase == PaintPhase::Background && !is_body()) { - context.painter().fill_rect(enclosing_int_rect(padded_rect), computed_values().background_color()); - - if (background_image() && background_image()->bitmap()) - context.painter().draw_tiled_bitmap(enclosing_int_rect(padded_rect), *background_image()->bitmap()); + auto background_rect = enclosing_int_rect(padded_rect); + context.painter().fill_rect(background_rect, computed_values().background_color()); + if (background_image() && background_image()->bitmap()) { + context.painter().blit_tiled(background_rect, *background_image()->bitmap(), background_image()->bitmap()->rect()); + } } if (phase == PaintPhase::Border) { |