diff options
author | Timothy Flynn <trflynn89@pm.me> | 2021-04-02 18:19:33 -0400 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-04-03 11:24:33 +0200 |
commit | fa9ba8bce53e24c983e2cac53d205e0ed8882b82 (patch) | |
tree | f2ad913e00e8aea6f9b498d3c8d8d0f2564cf207 | |
parent | bd5a91269f27ae1d8aac0027b57d9f2426bec5f4 (diff) | |
download | serenity-fa9ba8bce53e24c983e2cac53d205e0ed8882b82.zip |
LibWeb: Support rendering background images with 'background-repeat'
Update the painting of background images for both <body> nodes and other
non-initial nodes. Currently, only the following values are supported:
repeat, repeat-x, repeat-y, no-repeat
This also doesn't support the two-value syntax which allows for setting
horizontal and vertical repetition separately.
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.cpp | 13 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/DOM/Document.h | 1 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/Box.cpp | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp | 30 |
4 files changed, 55 insertions, 6 deletions
diff --git a/Userland/Libraries/LibWeb/DOM/Document.cpp b/Userland/Libraries/LibWeb/DOM/Document.cpp index 2327bdad7c..de13a63f11 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.cpp +++ b/Userland/Libraries/LibWeb/DOM/Document.cpp @@ -362,6 +362,19 @@ RefPtr<Gfx::Bitmap> Document::background_image() const return background_image->bitmap(); } +CSS::Repeat Document::background_repeat() const +{ + auto* body_element = body(); + if (!body_element) + return CSS::Repeat::Repeat; + + auto* body_layout_node = body_element->layout_node(); + if (!body_layout_node) + return CSS::Repeat::Repeat; + + return body_layout_node->computed_values().background_repeat(); +} + URL Document::complete_url(const String& string) const { return m_url.complete_url(string); diff --git a/Userland/Libraries/LibWeb/DOM/Document.h b/Userland/Libraries/LibWeb/DOM/Document.h index 1814b10f3f..d272db23f0 100644 --- a/Userland/Libraries/LibWeb/DOM/Document.h +++ b/Userland/Libraries/LibWeb/DOM/Document.h @@ -129,6 +129,7 @@ public: Color background_color(const Gfx::Palette&) const; RefPtr<Gfx::Bitmap> background_image() const; + CSS::Repeat background_repeat() const; Color link_color() const; void set_link_color(Color); diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index dd466a371a..eee05e81d7 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -49,6 +49,23 @@ void Box::paint(PaintContext& context, PaintPhase phase) auto background_rect = enclosing_int_rect(padded_rect); context.painter().fill_rect(background_rect, computed_values().background_color()); if (background_image() && background_image()->bitmap()) { + switch (computed_values().background_repeat()) { + case CSS::Repeat::Repeat: + // The background rect is already sized to align with 'repeat'. + break; + case CSS::Repeat::RepeatX: + background_rect.set_height(background_image()->bitmap()->height()); + break; + case CSS::Repeat::RepeatY: + background_rect.set_width(background_image()->bitmap()->width()); + break; + case CSS::Repeat::NoRepeat: + default: // FIXME: Support 'round' and 'square' + background_rect.set_width(background_image()->bitmap()->width()); + background_rect.set_height(background_image()->bitmap()->height()); + break; + } + context.painter().blit_tiled(background_rect, *background_image()->bitmap(), background_image()->bitmap()->rect()); } } diff --git a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp index b545670f97..3bf9b1d67d 100644 --- a/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp +++ b/Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp @@ -68,12 +68,30 @@ void InitialContainingBlockBox::paint_document_background(PaintContext& context) context.painter().translate(-context.viewport_rect().location()); if (auto background_bitmap = document().background_image()) { - Gfx::IntRect background_rect { - 0, - 0, - context.viewport_rect().x() + context.viewport_rect().width(), - context.viewport_rect().y() + context.viewport_rect().height() - }; + int painted_image_width = 0; + int painted_image_height = 0; + + switch (document().background_repeat()) { + case CSS::Repeat::Repeat: + painted_image_width = context.viewport_rect().x() + context.viewport_rect().width(); + painted_image_height = context.viewport_rect().y() + context.viewport_rect().height(); + break; + case CSS::Repeat::RepeatX: + painted_image_width = context.viewport_rect().x() + context.viewport_rect().width(); + painted_image_height = background_bitmap->rect().height(); + break; + case CSS::Repeat::RepeatY: + painted_image_width = background_bitmap->rect().width(); + painted_image_height = context.viewport_rect().y() + context.viewport_rect().height(); + break; + case CSS::Repeat::NoRepeat: + default: // FIXME: Support 'round' and 'square' + painted_image_width = background_bitmap->rect().width(); + painted_image_height = background_bitmap->rect().height(); + break; + } + + Gfx::IntRect background_rect { 0, 0, painted_image_width, painted_image_height }; context.painter().blit_tiled(background_rect, *background_bitmap, background_bitmap->rect()); } } |