diff options
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&); |