LibWeb: Parse and store filter property

This shares its implementation with `backdrop-filter`.
This commit is contained in:
Jelle Raaijmakers 2024-10-25 11:00:22 +02:00 committed by Andreas Kling
parent ea9abe26e1
commit 29974de852
Notes: github-actions[bot] 2024-10-26 09:28:54 +00:00
14 changed files with 104 additions and 75 deletions

View file

@ -104,6 +104,7 @@ counter-set: none
cx: 0px
cy: 0px
display: block
filter: none
flex-basis: auto
flex-direction: row
flex-grow: 0
@ -120,7 +121,7 @@ grid-row-start: auto
grid-template-areas: none
grid-template-columns: auto
grid-template-rows: auto
height: 2074px
height: 2091px
inline-size: auto
inset-block-end: auto
inset-block-start: auto

View file

@ -11,12 +11,12 @@
#include <AK/Optional.h>
#include <LibGfx/FontCascadeList.h>
#include <LibGfx/ScalingMode.h>
#include <LibWeb/CSS/BackdropFilter.h>
#include <LibWeb/CSS/CalculatedOr.h>
#include <LibWeb/CSS/Clip.h>
#include <LibWeb/CSS/ColumnCount.h>
#include <LibWeb/CSS/CountersSet.h>
#include <LibWeb/CSS/Display.h>
#include <LibWeb/CSS/Filter.h>
#include <LibWeb/CSS/GridTrackPlacement.h>
#include <LibWeb/CSS/GridTrackSize.h>
#include <LibWeb/CSS/LengthBox.h>
@ -55,7 +55,7 @@ struct QuotesData {
Vector<Array<FlyString, 2>> strings {};
};
struct ResolvedBackdropFilter {
struct ResolvedFilter {
struct Blur {
float radius;
};
@ -64,19 +64,19 @@ struct ResolvedBackdropFilter {
double offset_x;
double offset_y;
double radius;
Color color;
Gfx::Color color;
};
struct HueRotate {
float angle_degrees;
};
struct ColorOperation {
Filter::Color::Operation operation;
struct Color {
FilterOperation::Color::Type type;
float amount;
};
using FilterFunction = Variant<Blur, DropShadow, HueRotate, ColorOperation>;
using FilterFunction = Variant<Blur, DropShadow, HueRotate, Color>;
bool is_none() const { return filters.size() == 0; }
@ -121,7 +121,8 @@ public:
static CSS::Display display() { return CSS::Display { CSS::DisplayOutside::Inline, CSS::DisplayInside::Flow }; }
static Color color() { return Color::Black; }
static Color stop_color() { return Color::Black; }
static CSS::ResolvedBackdropFilter backdrop_filter() { return ResolvedBackdropFilter { .filters = {} }; }
static CSS::ResolvedFilter backdrop_filter() { return ResolvedFilter { .filters = {} }; }
static CSS::ResolvedFilter filter() { return ResolvedFilter { .filters = {} }; }
static Color background_color() { return Color::Transparent; }
static CSS::ListStyleType list_style_type() { return CSS::ListStyleType::Disc; }
static CSS::ListStylePosition list_style_position() { return CSS::ListStylePosition::Outside; }
@ -409,7 +410,8 @@ public:
CSS::JustifyContent justify_content() const { return m_noninherited.justify_content; }
CSS::JustifySelf justify_self() const { return m_noninherited.justify_self; }
CSS::JustifyItems justify_items() const { return m_noninherited.justify_items; }
CSS::ResolvedBackdropFilter const& backdrop_filter() const { return m_noninherited.backdrop_filter; }
CSS::ResolvedFilter const& backdrop_filter() const { return m_noninherited.backdrop_filter; }
CSS::ResolvedFilter const& filter() const { return m_noninherited.filter; }
Vector<ShadowData> const& box_shadow() const { return m_noninherited.box_shadow; }
CSS::BoxSizing box_sizing() const { return m_noninherited.box_sizing; }
CSS::Size const& width() const { return m_noninherited.width; }
@ -601,7 +603,8 @@ protected:
CSS::LengthBox inset { InitialValues::inset() };
CSS::LengthBox margin { InitialValues::margin() };
CSS::LengthBox padding { InitialValues::padding() };
CSS::ResolvedBackdropFilter backdrop_filter { InitialValues::backdrop_filter() };
CSS::ResolvedFilter backdrop_filter { InitialValues::backdrop_filter() };
CSS::ResolvedFilter filter { InitialValues::filter() };
BorderData border_left;
BorderData border_top;
BorderData border_right;
@ -746,7 +749,8 @@ public:
void set_list_style_type(CSS::ListStyleType value) { m_inherited.list_style_type = value; }
void set_list_style_position(CSS::ListStylePosition value) { m_inherited.list_style_position = value; }
void set_display(CSS::Display value) { m_noninherited.display = value; }
void set_backdrop_filter(CSS::ResolvedBackdropFilter backdrop_filter) { m_noninherited.backdrop_filter = move(backdrop_filter); }
void set_backdrop_filter(CSS::ResolvedFilter backdrop_filter) { m_noninherited.backdrop_filter = move(backdrop_filter); }
void set_filter(CSS::ResolvedFilter filter) { m_noninherited.filter = move(filter); }
void set_border_bottom_left_radius(CSS::BorderRadiusData value) { m_noninherited.border_bottom_left_radius = move(value); }
void set_border_bottom_right_radius(CSS::BorderRadiusData value) { m_noninherited.border_bottom_right_radius = move(value); }
void set_border_top_left_radius(CSS::BorderRadiusData value) { m_noninherited.border_top_left_radius = move(value); }

View file

@ -12,15 +12,15 @@
namespace Web::CSS {
class BackdropFilter {
class Filter {
public:
BackdropFilter() = default;
BackdropFilter(FilterValueListStyleValue const& filter_value_list)
Filter() = default;
Filter(FilterValueListStyleValue const& filter_value_list)
: m_filter_value_list { filter_value_list } {};
static inline BackdropFilter make_none()
static Filter make_none()
{
return BackdropFilter {};
return Filter {};
}
bool has_filters() const { return m_filter_value_list; }

View file

@ -5156,7 +5156,7 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
auto filter_token_to_operation = [&](auto filter) {
VERIFY(to_underlying(filter) < to_underlying(FilterToken::Blur));
return static_cast<Filter::Color::Operation>(filter);
return static_cast<FilterOperation::Color::Type>(filter);
};
auto parse_number_percentage = [&](auto& token) -> Optional<NumberPercentage> {
@ -5205,13 +5205,13 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
if (filter_token == FilterToken::Blur) {
// blur( <length>? )
if (!tokens.has_next_token())
return Filter::Blur {};
return FilterOperation::Blur {};
auto blur_radius = parse_length(tokens);
tokens.discard_whitespace();
if (!blur_radius.has_value())
return {};
// FIXME: Support calculated radius
return if_no_more_tokens_return(Filter::Blur { blur_radius->value() });
return if_no_more_tokens_return(FilterOperation::Blur { blur_radius->value() });
} else if (filter_token == FilterToken::DropShadow) {
if (!tokens.has_next_token())
return {};
@ -5240,17 +5240,17 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
}
}
// FIXME: Support calculated offsets and radius
return if_no_more_tokens_return(Filter::DropShadow { x_offset->value(), y_offset->value(), maybe_radius.map([](auto& it) { return it.value(); }), maybe_color->to_color({}) });
return if_no_more_tokens_return(FilterOperation::DropShadow { x_offset->value(), y_offset->value(), maybe_radius.map([](auto& it) { return it.value(); }), maybe_color->to_color({}) });
} else if (filter_token == FilterToken::HueRotate) {
// hue-rotate( [ <angle> | <zero> ]? )
if (!tokens.has_next_token())
return Filter::HueRotate {};
return FilterOperation::HueRotate {};
auto& token = tokens.consume_a_token();
if (token.is(Token::Type::Number)) {
// hue-rotate(0)
auto number = token.token().number();
if (number.is_integer() && number.integer_value() == 0)
return if_no_more_tokens_return(Filter::HueRotate { Filter::HueRotate::Zero {} });
return if_no_more_tokens_return(FilterOperation::HueRotate { FilterOperation::HueRotate::Zero {} });
return {};
}
if (!token.is(Token::Type::Dimension))
@ -5261,7 +5261,7 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
if (!angle_unit.has_value())
return {};
Angle angle { angle_value, angle_unit.release_value() };
return if_no_more_tokens_return(Filter::HueRotate { angle });
return if_no_more_tokens_return(FilterOperation::HueRotate { angle });
} else {
// Simple filters:
// brightness( <number-percentage>? )
@ -5272,11 +5272,11 @@ RefPtr<CSSStyleValue> Parser::parse_filter_value_list_value(TokenStream<Componen
// sepia( <number-percentage>? )
// saturate( <number-percentage>? )
if (!tokens.has_next_token())
return Filter::Color { filter_token_to_operation(filter_token) };
return FilterOperation::Color { filter_token_to_operation(filter_token) };
auto amount = parse_number_percentage(tokens.consume_a_token());
if (!amount.has_value())
return {};
return if_no_more_tokens_return(Filter::Color { filter_token_to_operation(filter_token), *amount });
return if_no_more_tokens_return(FilterOperation::Color { filter_token_to_operation(filter_token), *amount });
}
};
@ -7860,6 +7860,7 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(Prope
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::BackdropFilter:
case PropertyID::Filter:
if (auto parsed_value = parse_filter_value_list_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
return ParseError::SyntaxError;

View file

@ -1065,6 +1065,16 @@
"fill-rule"
]
},
"filter": {
"affects-layout": false,
"animation-type": "custom",
"inherited": false,
"initial": "none",
"__comment": "FIXME: List `filter-value-list` as a valid-type once it's generically supported.",
"valid-identifiers": [
"none"
]
},
"flex": {
"inherited": false,
"initial": "0 1 auto",

View file

@ -613,12 +613,20 @@ Optional<CSS::Appearance> StyleProperties::appearance() const
return appearance;
}
CSS::BackdropFilter StyleProperties::backdrop_filter() const
CSS::Filter StyleProperties::backdrop_filter() const
{
auto value = property(CSS::PropertyID::BackdropFilter);
if (value->is_filter_value_list())
return BackdropFilter(value->as_filter_value_list());
return BackdropFilter::make_none();
return Filter(value->as_filter_value_list());
return Filter::make_none();
}
CSS::Filter StyleProperties::filter() const
{
auto value = property(CSS::PropertyID::Filter);
if (value->is_filter_value_list())
return Filter(value->as_filter_value_list());
return Filter::make_none();
}
Optional<CSS::Positioning> StyleProperties::position() const

View file

@ -137,7 +137,8 @@ public:
Optional<CSS::AlignItems> align_items() const;
Optional<CSS::AlignSelf> align_self() const;
Optional<CSS::Appearance> appearance() const;
CSS::BackdropFilter backdrop_filter() const;
CSS::Filter backdrop_filter() const;
CSS::Filter filter() const;
float opacity() const;
Optional<CSS::Visibility> visibility() const;
Optional<CSS::ImageRendering> image_rendering() const;

View file

@ -13,7 +13,7 @@
namespace Web::CSS {
float Filter::Blur::resolved_radius(Layout::Node const& node) const
float FilterOperation::Blur::resolved_radius(Layout::Node const& node) const
{
// Default value when omitted is 0px.
auto sigma = 0;
@ -23,7 +23,7 @@ float Filter::Blur::resolved_radius(Layout::Node const& node) const
return sigma * 2;
}
float Filter::HueRotate::angle_degrees() const
float FilterOperation::HueRotate::angle_degrees() const
{
// Default value when omitted is 0deg.
if (!angle.has_value())
@ -31,7 +31,7 @@ float Filter::HueRotate::angle_degrees() const
return angle->visit([&](Angle const& a) { return a.to_degrees(); }, [&](auto) { return 0.0; });
}
float Filter::Color::resolved_amount() const
float FilterOperation::Color::resolved_amount() const
{
if (amount.has_value()) {
if (amount->is_percentage())
@ -50,12 +50,12 @@ String FilterValueListStyleValue::to_string() const
if (!first)
builder.append(' ');
filter_function.visit(
[&](Filter::Blur const& blur) {
[&](FilterOperation::Blur const& blur) {
builder.append("blur("sv);
if (blur.radius.has_value())
builder.append(blur.radius->to_string());
},
[&](Filter::DropShadow const& drop_shadow) {
[&](FilterOperation::DropShadow const& drop_shadow) {
builder.appendff("drop-shadow({} {}"sv,
drop_shadow.offset_x, drop_shadow.offset_y);
if (drop_shadow.radius.has_value())
@ -65,7 +65,7 @@ String FilterValueListStyleValue::to_string() const
serialize_a_srgb_value(builder, *drop_shadow.color);
}
},
[&](Filter::HueRotate const& hue_rotate) {
[&](FilterOperation::HueRotate const& hue_rotate) {
builder.append("hue-rotate("sv);
if (hue_rotate.angle.has_value()) {
hue_rotate.angle->visit(
@ -77,23 +77,23 @@ String FilterValueListStyleValue::to_string() const
});
}
},
[&](Filter::Color const& color) {
[&](FilterOperation::Color const& color) {
builder.appendff("{}(",
[&] {
switch (color.operation) {
case Filter::Color::Operation::Brightness:
case FilterOperation::Color::Type::Brightness:
return "brightness"sv;
case Filter::Color::Operation::Contrast:
case FilterOperation::Color::Type::Contrast:
return "contrast"sv;
case Filter::Color::Operation::Grayscale:
case FilterOperation::Color::Type::Grayscale:
return "grayscale"sv;
case Filter::Color::Operation::Invert:
case FilterOperation::Color::Type::Invert:
return "invert"sv;
case Filter::Color::Operation::Opacity:
case FilterOperation::Color::Type::Opacity:
return "opacity"sv;
case Filter::Color::Operation::Saturate:
case FilterOperation::Color::Type::Saturate:
return "saturate"sv;
case Filter::Color::Operation::Sepia:
case FilterOperation::Color::Type::Sepia:
return "sepia"sv;
default:
VERIFY_NOT_REACHED();

View file

@ -16,7 +16,7 @@
namespace Web::CSS {
namespace Filter {
namespace FilterOperation {
struct Blur {
Optional<Length> radius {};
@ -43,7 +43,7 @@ struct HueRotate {
};
struct Color {
enum class Operation {
enum class Type {
Brightness,
Contrast,
Grayscale,
@ -59,7 +59,7 @@ struct Color {
};
using FilterFunction = Variant<Filter::Blur, Filter::DropShadow, Filter::HueRotate, Filter::Color>;
using FilterFunction = Variant<FilterOperation::Blur, FilterOperation::DropShadow, FilterOperation::HueRotate, FilterOperation::Color>;
class FilterValueListStyleValue final : public StyleValueWithDefaultOperators<FilterValueListStyleValue> {
public:

View file

@ -512,34 +512,38 @@ void NodeWithStyle::apply_style(const CSS::StyleProperties& computed_style)
computed_values.set_order(computed_style.order());
computed_values.set_clip(computed_style.clip());
if (computed_style.backdrop_filter().has_filters()) {
CSS::ResolvedBackdropFilter resolved_backdrop_filter;
for (auto& filter : computed_style.backdrop_filter().filters()) {
auto resolve_filter = [this](CSS::Filter const& computed_filter) -> CSS::ResolvedFilter {
CSS::ResolvedFilter resolved_filter;
for (auto const& filter : computed_filter.filters()) {
filter.visit(
[&](CSS::Filter::Blur const& blur) {
resolved_backdrop_filter.filters.append(CSS::ResolvedBackdropFilter::Blur {
[&](CSS::FilterOperation::Blur const& blur) {
resolved_filter.filters.append(CSS::ResolvedFilter::Blur {
.radius = blur.resolved_radius(*this) });
},
[&](CSS::Filter::DropShadow const& drop_shadow) {
[&](CSS::FilterOperation::DropShadow const& drop_shadow) {
// The default value for omitted values is missing length values set to 0
// and the missing used color is taken from the color property.
resolved_backdrop_filter.filters.append(CSS::ResolvedBackdropFilter::DropShadow {
resolved_filter.filters.append(CSS::ResolvedFilter::DropShadow {
.offset_x = drop_shadow.offset_x.to_px(*this).to_double(),
.offset_y = drop_shadow.offset_y.to_px(*this).to_double(),
.radius = drop_shadow.radius.has_value() ? drop_shadow.radius->to_px(*this).to_double() : 0.0,
.color = drop_shadow.color.has_value() ? *drop_shadow.color : this->computed_values().color() });
},
[&](CSS::Filter::Color const& color_operation) {
resolved_backdrop_filter.filters.append(CSS::ResolvedBackdropFilter::ColorOperation {
.operation = color_operation.operation,
[&](CSS::FilterOperation::Color const& color_operation) {
resolved_filter.filters.append(CSS::ResolvedFilter::Color {
.type = color_operation.operation,
.amount = color_operation.resolved_amount() });
},
[&](CSS::Filter::HueRotate const& hue_rotate) {
resolved_backdrop_filter.filters.append(CSS::ResolvedBackdropFilter::HueRotate { .angle_degrees = hue_rotate.angle_degrees() });
[&](CSS::FilterOperation::HueRotate const& hue_rotate) {
resolved_filter.filters.append(CSS::ResolvedFilter::HueRotate { .angle_degrees = hue_rotate.angle_degrees() });
});
}
computed_values.set_backdrop_filter(resolved_backdrop_filter);
}
return resolved_filter;
};
if (computed_style.backdrop_filter().has_filters())
computed_values.set_backdrop_filter(resolve_filter(computed_style.backdrop_filter()));
if (computed_style.filter().has_filters())
computed_values.set_filter(resolve_filter(computed_style.filter()));
auto justify_content = computed_style.justify_content();
if (justify_content.has_value())

View file

@ -285,7 +285,7 @@ struct DrawLine {
struct ApplyBackdropFilter {
Gfx::IntRect backdrop_region;
BorderRadiiData border_radii_data;
CSS::ResolvedBackdropFilter backdrop_filter;
CSS::ResolvedFilter backdrop_filter;
[[nodiscard]] Gfx::IntRect bounding_rect() const { return backdrop_region; }

View file

@ -964,18 +964,18 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
for (auto const& filter_function : command.backdrop_filter.filters) {
// See: https://drafts.fxtf.org/filter-effects-1/#supported-filter-functions
filter_function.visit(
[&](CSS::ResolvedBackdropFilter::Blur const& blur_filter) {
[&](CSS::ResolvedFilter::Blur const& blur_filter) {
auto blur_image_filter = SkImageFilters::Blur(blur_filter.radius, blur_filter.radius, nullptr);
canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, nullptr, blur_image_filter.get(), 0));
canvas.restore();
},
[&](CSS::ResolvedBackdropFilter::ColorOperation const& color) {
[&](CSS::ResolvedFilter::Color const& color) {
auto amount = clamp(color.amount, 0.0f, 1.0f);
// Matrices are taken from https://drafts.fxtf.org/filter-effects-1/#FilterPrimitiveRepresentation
sk_sp<SkColorFilter> color_filter;
switch (color.operation) {
case CSS::Filter::Color::Operation::Grayscale: {
switch (color.type) {
case CSS::FilterOperation::Color::Type::Grayscale: {
float matrix[20] = {
0.2126f + 0.7874f * (1 - amount), 0.7152f - 0.7152f * (1 - amount), 0.0722f - 0.0722f * (1 - amount), 0, 0,
0.2126f - 0.2126f * (1 - amount), 0.7152f + 0.2848f * (1 - amount), 0.0722f - 0.0722f * (1 - amount), 0, 0,
@ -985,7 +985,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Brightness: {
case CSS::FilterOperation::Color::Type::Brightness: {
float matrix[20] = {
amount, 0, 0, 0, 0,
0, amount, 0, 0, 0,
@ -995,7 +995,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Contrast: {
case CSS::FilterOperation::Color::Type::Contrast: {
float intercept = -(0.5f * amount) + 0.5f;
float matrix[20] = {
amount, 0, 0, 0, intercept,
@ -1006,7 +1006,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Invert: {
case CSS::FilterOperation::Color::Type::Invert: {
float matrix[20] = {
1 - 2 * amount, 0, 0, 0, amount,
0, 1 - 2 * amount, 0, 0, amount,
@ -1016,7 +1016,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Opacity: {
case CSS::FilterOperation::Color::Type::Opacity: {
float matrix[20] = {
1, 0, 0, 0, 0,
0, 1, 0, 0, 0,
@ -1026,7 +1026,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Sepia: {
case CSS::FilterOperation::Color::Type::Sepia: {
float matrix[20] = {
0.393f + 0.607f * (1 - amount), 0.769f - 0.769f * (1 - amount), 0.189f - 0.189f * (1 - amount), 0, 0,
0.349f - 0.349f * (1 - amount), 0.686f + 0.314f * (1 - amount), 0.168f - 0.168f * (1 - amount), 0, 0,
@ -1036,7 +1036,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
color_filter = SkColorFilters::Matrix(matrix);
break;
}
case CSS::Filter::Color::Operation::Saturate: {
case CSS::FilterOperation::Color::Type::Saturate: {
float matrix[20] = {
0.213f + 0.787f * amount, 0.715f - 0.715f * amount, 0.072f - 0.072f * amount, 0, 0,
0.213f - 0.213f * amount, 0.715f + 0.285f * amount, 0.072f - 0.072f * amount, 0, 0,
@ -1054,7 +1054,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, nullptr, image_filter.get(), 0));
canvas.restore();
},
[&](CSS::ResolvedBackdropFilter::HueRotate const& hue_rotate) {
[&](CSS::ResolvedFilter::HueRotate const& hue_rotate) {
float radians = AK::to_radians(hue_rotate.angle_degrees);
auto cosA = cos(radians);
@ -1082,7 +1082,7 @@ void DisplayListPlayerSkia::apply_backdrop_filter(ApplyBackdropFilter const& com
canvas.saveLayer(SkCanvas::SaveLayerRec(nullptr, nullptr, image_filter.get(), 0));
canvas.restore();
},
[&](CSS::ResolvedBackdropFilter::DropShadow const&) {
[&](CSS::ResolvedFilter::DropShadow const&) {
dbgln("TODO: Implement drop-shadow() filter function!");
});
}

View file

@ -299,7 +299,7 @@ void DisplayListRecorder::pop_stacking_context()
append(PopStackingContext {});
}
void DisplayListRecorder::apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedBackdropFilter const& backdrop_filter)
void DisplayListRecorder::apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedFilter const& backdrop_filter)
{
if (backdrop_region.is_empty())
return;

View file

@ -124,7 +124,7 @@ public:
void add_rounded_rect_clip(CornerRadii corner_radii, Gfx::IntRect border_rect, CornerClip corner_clip);
void add_mask(RefPtr<DisplayList> display_list, Gfx::IntRect rect);
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedBackdropFilter const& backdrop_filter);
void apply_backdrop_filter(Gfx::IntRect const& backdrop_region, BorderRadiiData const& border_radii_data, CSS::ResolvedFilter const& backdrop_filter);
void paint_outer_box_shadow_params(PaintBoxShadowParams params);
void paint_inner_box_shadow_params(PaintBoxShadowParams params);