LibWeb: Parse and store filter
property
This shares its implementation with `backdrop-filter`.
This commit is contained in:
parent
ea9abe26e1
commit
29974de852
Notes:
github-actions[bot]
2024-10-26 09:28:54 +00:00
Author: https://github.com/gmta Commit: https://github.com/LadybirdBrowser/ladybird/commit/29974de852f Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/1963
14 changed files with 104 additions and 75 deletions
|
@ -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
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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; }
|
|
@ -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;
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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!");
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue