diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-02-08 15:33:27 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-08 17:45:51 +0100 |
commit | 103613a3a933a0213c88064f65b1d3e5ab48ec3b (patch) | |
tree | e25fbe7b0faf1f749e8353e8d7028653f8b8b112 /Userland/Libraries/LibWeb | |
parent | 10c6c77b5c252ac88a5411b8188b8ee4ed190827 (diff) | |
download | serenity-103613a3a933a0213c88064f65b1d3e5ab48ec3b.zip |
LibWeb: Incorporate spread-distance into box-shadow rendering
We also pass whether the shadow goes inside or outside the element. Only
outer shadows are rendered currently, and inner ones may want to be
handled separately from them, as they will never interfere with each
other.
Diffstat (limited to 'Userland/Libraries/LibWeb')
7 files changed, 27 insertions, 12 deletions
diff --git a/Userland/Libraries/LibWeb/CSS/ComputedValues.h b/Userland/Libraries/LibWeb/CSS/ComputedValues.h index df0f42bb5a..ed2eefae01 100644 --- a/Userland/Libraries/LibWeb/CSS/ComputedValues.h +++ b/Userland/Libraries/LibWeb/CSS/ComputedValues.h @@ -76,10 +76,12 @@ struct FlexBasisData { }; struct BoxShadowData { + Color color {}; CSS::Length offset_x {}; CSS::Length offset_y {}; CSS::Length blur_radius {}; - Color color {}; + CSS::Length spread_distance {}; + CSS::BoxShadowPlacement placement { CSS::BoxShadowPlacement::Outer }; }; class ComputedValues { diff --git a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp index 72b463d07b..1338b5d160 100644 --- a/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp +++ b/Userland/Libraries/LibWeb/CSS/ResolvedCSSStyleDeclaration.cpp @@ -523,8 +523,7 @@ RefPtr<StyleValue> ResolvedCSSStyleDeclaration::style_value_for_property(Layout: return {}; auto make_box_shadow_style_value = [](BoxShadowData const& data) { - // FIXME: Add extra properties to BoxShadowData so we can include them here! - return BoxShadowStyleValue::create(data.color, data.offset_x, data.offset_y, data.blur_radius, Length::make_px(0), BoxShadowPlacement::Outer); + return BoxShadowStyleValue::create(data.color, data.offset_x, data.offset_y, data.blur_radius, data.spread_distance, data.placement); }; if (box_shadow_layers.size() == 1) diff --git a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp index 65d2b054e7..3673aa6639 100644 --- a/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp +++ b/Userland/Libraries/LibWeb/CSS/StyleProperties.cpp @@ -778,7 +778,7 @@ Vector<BoxShadowData> StyleProperties::box_shadow() const auto value = value_or_error.value(); auto make_box_shadow_data = [](BoxShadowStyleValue const& box) { - return BoxShadowData { box.offset_x(), box.offset_y(), box.blur_radius(), box.color() }; + return BoxShadowData { box.color(), box.offset_x(), box.offset_y(), box.blur_radius(), box.spread_distance(), box.placement() }; }; if (value->is_value_list()) { diff --git a/Userland/Libraries/LibWeb/Layout/Box.cpp b/Userland/Libraries/LibWeb/Layout/Box.cpp index 897e1ae375..6786d62d75 100644 --- a/Userland/Libraries/LibWeb/Layout/Box.cpp +++ b/Userland/Libraries/LibWeb/Layout/Box.cpp @@ -106,10 +106,12 @@ void Box::paint_box_shadow(PaintContext& context) resolved_box_shadow_data.ensure_capacity(box_shadow_data.size()); for (auto const& layer : box_shadow_data) { resolved_box_shadow_data.empend( + layer.color, static_cast<int>(layer.offset_x.resolved_or_zero(*this).to_px(*this)), static_cast<int>(layer.offset_y.resolved_or_zero(*this).to_px(*this)), static_cast<int>(layer.blur_radius.resolved_or_zero(*this).to_px(*this)), - layer.color); + static_cast<int>(layer.spread_distance.resolved_or_zero(*this).to_px(*this)), + layer.placement == CSS::BoxShadowPlacement::Outer ? Painting::BoxShadowPlacement::Outer : Painting::BoxShadowPlacement::Inner); } Painting::paint_box_shadow(context, enclosing_int_rect(bordered_rect()), resolved_box_shadow_data); } diff --git a/Userland/Libraries/LibWeb/Layout/InlineNode.cpp b/Userland/Libraries/LibWeb/Layout/InlineNode.cpp index c4ba68df0f..1ac4fd6b98 100644 --- a/Userland/Libraries/LibWeb/Layout/InlineNode.cpp +++ b/Userland/Libraries/LibWeb/Layout/InlineNode.cpp @@ -48,10 +48,12 @@ void InlineNode::paint(PaintContext& context, PaintPhase phase) resolved_box_shadow_data.ensure_capacity(computed_box_shadow.size()); for (auto const& layer : computed_box_shadow) { resolved_box_shadow_data.empend( + layer.color, static_cast<int>(layer.offset_x.resolved_or_zero(*this).to_px(*this)), static_cast<int>(layer.offset_y.resolved_or_zero(*this).to_px(*this)), static_cast<int>(layer.blur_radius.resolved_or_zero(*this).to_px(*this)), - layer.color); + static_cast<int>(layer.spread_distance.resolved_or_zero(*this).to_px(*this)), + layer.placement == CSS::BoxShadowPlacement::Outer ? Painting::BoxShadowPlacement::Outer : Painting::BoxShadowPlacement::Inner); } Painting::paint_box_shadow(context, enclosing_int_rect(absolute_fragment_rect), resolved_box_shadow_data); } diff --git a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp index 5fa8eafdf5..95644b4c12 100644 --- a/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp +++ b/Userland/Libraries/LibWeb/Painting/ShadowPainting.cpp @@ -21,17 +21,20 @@ void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, V // Note: Box-shadow layers are ordered front-to-back, so we paint them in reverse for (int layer_index = box_shadow_layers.size() - 1; layer_index >= 0; layer_index--) { auto& box_shadow_data = box_shadow_layers[layer_index]; + // FIXME: Paint inset shadows. + if (box_shadow_data.placement != BoxShadowPlacement::Outer) + continue; Gfx::IntRect bitmap_rect = { 0, 0, - content_rect.width() + 4 * box_shadow_data.blur_radius, - content_rect.height() + 4 * box_shadow_data.blur_radius + content_rect.width() + (2 * box_shadow_data.spread_distance) + (4 * box_shadow_data.blur_radius), + content_rect.height() + (2 * box_shadow_data.spread_distance) + (4 * box_shadow_data.blur_radius) }; Gfx::IntPoint blur_rect_position = { - content_rect.x() - 2 * box_shadow_data.blur_radius + box_shadow_data.offset_x, - content_rect.y() - 2 * box_shadow_data.blur_radius + box_shadow_data.offset_y + content_rect.x() - box_shadow_data.spread_distance - (2 * box_shadow_data.blur_radius) + box_shadow_data.offset_x, + content_rect.y() - box_shadow_data.spread_distance - (2 * box_shadow_data.blur_radius) + box_shadow_data.offset_y }; if (bitmap_rect.is_empty()) @@ -45,7 +48,7 @@ void paint_box_shadow(PaintContext& context, Gfx::IntRect const& content_rect, V auto new_bitmap = bitmap_or_error.release_value_but_fixme_should_propagate_errors(); Gfx::Painter painter(*new_bitmap); - painter.fill_rect({ { 2 * box_shadow_data.blur_radius, 2 * box_shadow_data.blur_radius }, content_rect.size() }, box_shadow_data.color); + painter.fill_rect({ { 2 * box_shadow_data.blur_radius, 2 * box_shadow_data.blur_radius }, { content_rect.width() + (2 * box_shadow_data.spread_distance), content_rect.height() + (2 * box_shadow_data.spread_distance) } }, box_shadow_data.color); Gfx::FastBoxBlurFilter filter(*new_bitmap); filter.apply_three_passes(box_shadow_data.blur_radius); diff --git a/Userland/Libraries/LibWeb/Painting/ShadowPainting.h b/Userland/Libraries/LibWeb/Painting/ShadowPainting.h index 4484a76f8c..9c46f56679 100644 --- a/Userland/Libraries/LibWeb/Painting/ShadowPainting.h +++ b/Userland/Libraries/LibWeb/Painting/ShadowPainting.h @@ -11,11 +11,18 @@ namespace Web::Painting { +enum class BoxShadowPlacement { + Outer, + Inner, +}; + struct BoxShadowData { + Gfx::Color color; int offset_x; int offset_y; int blur_radius; - Gfx::Color color; + int spread_distance; + BoxShadowPlacement placement; }; void paint_box_shadow(PaintContext&, Gfx::IntRect const&, Vector<BoxShadowData> const&); |