summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2021-11-17 12:52:46 +0000
committerAndreas Kling <kling@serenityos.org>2021-11-17 22:20:01 +0100
commit92708746c874fe4975a51ff3232f8b34e95cfd23 (patch)
tree8d3c485b0e837050b36dbcea494416bf11d582dc /Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
parent493435c655dcd54f77a40a4f5c7bd48d9be0510d (diff)
downloadserenity-92708746c874fe4975a51ff3232f8b34e95cfd23.zip
LibWeb: Implement `background-repeat: round` :^)
Diffstat (limited to 'Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp')
-rw-r--r--Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp32
1 files changed, 32 insertions, 0 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
index 107e580374..0b60e82e68 100644
--- a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
+++ b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp
@@ -101,6 +101,34 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
}
}
+ // If background-repeat is round for one (or both) dimensions, there is a second step.
+ // The UA must scale the image in that dimension (or both dimensions) so that it fits a
+ // whole number of times in the background positioning area.
+ if (layer.repeat_x == CSS::Repeat::Round || layer.repeat_y == CSS::Repeat::Round) {
+ // If X ≠ 0 is the width of the image after step one and W is the width of the
+ // background positioning area, then the rounded width X' = W / round(W / X)
+ // where round() is a function that returns the nearest natural number
+ // (integer greater than zero).
+ if (layer.repeat_x == CSS::Repeat::Round) {
+ image_rect.set_width((float)background_positioning_area.width() / roundf((float)background_positioning_area.width() / (float)image_rect.width()));
+ }
+ if (layer.repeat_y == CSS::Repeat::Round) {
+ image_rect.set_height((float)background_positioning_area.height() / roundf((float)background_positioning_area.height() / (float)image_rect.height()));
+ }
+
+ // If background-repeat is round for one dimension only and if background-size is auto
+ // for the other dimension, then there is a third step: that other dimension is scaled
+ // so that the original aspect ratio is restored.
+ if (layer.repeat_x != layer.repeat_y) {
+ if (layer.size_x.is_auto()) {
+ image_rect.set_width((float)image.width() * ((float)image_rect.height() / (float)image.height()));
+ }
+ if (layer.size_y.is_auto()) {
+ image_rect.set_height((float)image.height() * ((float)image_rect.width() / (float)image.width()));
+ }
+ }
+ }
+
int space_x = background_positioning_area.width() - image_rect.width();
int space_y = background_positioning_area.height() - image_rect.height();
@@ -127,6 +155,8 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
switch (layer.repeat_x) {
case CSS::Repeat::Round:
+ x_step = image_rect.width();
+ repeat_x = true;
break;
case CSS::Repeat::Space: {
int whole_images = background_positioning_area.width() / image_rect.width();
@@ -156,6 +186,8 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet
switch (layer.repeat_y) {
case CSS::Repeat::Round:
+ y_step = image_rect.height();
+ repeat_y = true;
break;
case CSS::Repeat::Space: {
int whole_images = background_positioning_area.height() / image_rect.height();