1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-06-02 23:18:14 +00:00

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.
This commit is contained in:
Mihai Parparita 2021-03-05 16:42:50 -08:00 committed by Andreas Kling
parent e97865e982
commit c2f3d3afe1
3 changed files with 28 additions and 4 deletions

View file

@ -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);
}
}
}
}

View file

@ -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);

View file

@ -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) {