summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTimothy Flynn <trflynn89@pm.me>2021-04-02 18:19:33 -0400
committerAndreas Kling <kling@serenityos.org>2021-04-03 11:24:33 +0200
commitfa9ba8bce53e24c983e2cac53d205e0ed8882b82 (patch)
treef2ad913e00e8aea6f9b498d3c8d8d0f2564cf207
parentbd5a91269f27ae1d8aac0027b57d9f2426bec5f4 (diff)
downloadserenity-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.cpp13
-rw-r--r--Userland/Libraries/LibWeb/DOM/Document.h1
-rw-r--r--Userland/Libraries/LibWeb/Layout/Box.cpp17
-rw-r--r--Userland/Libraries/LibWeb/Layout/InitialContainingBlockBox.cpp30
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());
}
}