diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2021-11-16 16:27:03 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-11-17 22:20:01 +0100 |
commit | 3d1ee5b2de81bf3aa3c3fb21b8673a06b97902be (patch) | |
tree | 442aa6a902eb4cf149d149ee0c84e1237cb1d2d9 /Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp | |
parent | 80642b4f9d9eee618a8ce9008721ddccb3adb88f (diff) | |
download | serenity-3d1ee5b2de81bf3aa3c3fb21b8673a06b97902be.zip |
LibWeb: Implement background-size :^)
This is including the `cover` and `contain` modes.
Diffstat (limited to 'Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp')
-rw-r--r-- | Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp index e32c6ea921..b16f4114bf 100644 --- a/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/BackgroundPainting.cpp @@ -47,6 +47,7 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet // Note: Background layers are ordered front-to-back, so we paint them in reverse for (int layer_index = background_layers->size() - 1; layer_index >= 0; layer_index--) { auto& layer = background_layers->at(layer_index); + // TODO: Gradients! if (!layer.image || !layer.image->bitmap()) continue; auto& image = *layer.image->bitmap(); @@ -57,11 +58,49 @@ void paint_background(PaintContext& context, Layout::NodeWithStyleAndBoxModelMet painter.add_clip_rect(clip_rect); // FIXME: Attachment - // FIXME: Size - Gfx::IntRect image_rect { border_rect.x(), border_rect.y(), image.width(), image.height() }; // Origin auto background_positioning_area = get_box(layer.origin); + + // Size + Gfx::IntRect image_rect; + switch (layer.size_type) { + case CSS::BackgroundSize::Contain: { + float max_width_ratio = (float)background_positioning_area.width() / (float)image.width(); + float max_height_ratio = (float)background_positioning_area.height() / (float)image.height(); + float ratio = min(max_width_ratio, max_height_ratio); + image_rect.set_size(roundf(image.width() * ratio), roundf(image.height() * ratio)); + break; + } + case CSS::BackgroundSize::Cover: { + float max_width_ratio = (float)background_positioning_area.width() / (float)image.width(); + float max_height_ratio = (float)background_positioning_area.height() / (float)image.height(); + float ratio = max(max_width_ratio, max_height_ratio); + image_rect.set_size(roundf(image.width() * ratio), roundf(image.height() * ratio)); + break; + } + case CSS::BackgroundSize::LengthPercentage: { + int width; + int height; + if (layer.size_x.is_auto() && layer.size_y.is_auto()) { + width = image.width(); + height = image.height(); + } else if (layer.size_x.is_auto()) { + height = layer.size_y.resolved_or_zero(layout_node, background_positioning_area.height()).to_px(layout_node); + width = roundf(image.width() * ((float)height / (float)image.height())); + } else if (layer.size_y.is_auto()) { + width = layer.size_x.resolved_or_zero(layout_node, background_positioning_area.width()).to_px(layout_node); + height = roundf(image.height() * ((float)width / (float)image.width())); + } else { + width = layer.size_x.resolved_or_zero(layout_node, background_positioning_area.width()).to_px(layout_node); + height = layer.size_y.resolved_or_zero(layout_node, background_positioning_area.height()).to_px(layout_node); + } + + image_rect.set_size(width, height); + break; + } + } + int space_x = background_positioning_area.width() - image_rect.width(); int space_y = background_positioning_area.height() - image_rect.height(); |