diff --git a/Libraries/LibWeb/SVG/SVGFEBlendElement.cpp b/Libraries/LibWeb/SVG/SVGFEBlendElement.cpp index 87b1f5c7d7c..a11a7a845c7 100644 --- a/Libraries/LibWeb/SVG/SVGFEBlendElement.cpp +++ b/Libraries/LibWeb/SVG/SVGFEBlendElement.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include @@ -33,6 +34,24 @@ void SVGFEBlendElement::visit_edges(Cell::Visitor& visitor) visitor.visit(m_in2); } +void SVGFEBlendElement::attribute_changed(FlyString const& name, Optional const& old_value, Optional const& new_value, Optional const& namespace_) +{ + Base::attribute_changed(name, old_value, new_value, namespace_); + + if (name == SVG::AttributeNames::mode) { + auto parse_mix_blend_mode = [](Optional const& value) -> Optional { + if (!value.has_value()) + return {}; + auto keyword = CSS::keyword_from_string(*value); + if (!keyword.has_value()) + return {}; + return CSS::keyword_to_mix_blend_mode(*keyword); + }; + + m_mode = parse_mix_blend_mode(new_value); + } +} + GC::Ref SVGFEBlendElement::in1() { if (!m_in1) @@ -49,10 +68,14 @@ GC::Ref SVGFEBlendElement::in2() return *m_in2; } -GC::Ref SVGFEBlendElement::mode() const +Gfx::CompositingAndBlendingOperator SVGFEBlendElement::mode() const { - // FIXME: Resolve the actual value from AttributeName::mode. - return SVGAnimatedEnumeration::create(realm(), 1); + return Painting::mix_blend_mode_to_compositing_and_blending_operator(m_mode.value_or(CSS::MixBlendMode::Normal)); +} + +GC::Ref SVGFEBlendElement::mode_for_bindings() const +{ + return SVGAnimatedEnumeration::create(realm(), to_underlying(mode())); } } diff --git a/Libraries/LibWeb/SVG/SVGFEBlendElement.h b/Libraries/LibWeb/SVG/SVGFEBlendElement.h index 2c94da70112..641b8dd1f4f 100644 --- a/Libraries/LibWeb/SVG/SVGFEBlendElement.h +++ b/Libraries/LibWeb/SVG/SVGFEBlendElement.h @@ -24,7 +24,9 @@ public: GC::Ref in1(); GC::Ref in2(); - GC::Ref mode() const; + + Gfx::CompositingAndBlendingOperator mode() const; + GC::Ref mode_for_bindings() const; private: SVGFEBlendElement(DOM::Document&, DOM::QualifiedName); @@ -32,8 +34,12 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; + virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& new_value, Optional const& namespace_) override; + GC::Ptr m_in1; GC::Ptr m_in2; + + Optional m_mode; }; } diff --git a/Libraries/LibWeb/SVG/SVGFEBlendElement.idl b/Libraries/LibWeb/SVG/SVGFEBlendElement.idl index 62d88aba8e0..93c0c828a98 100644 --- a/Libraries/LibWeb/SVG/SVGFEBlendElement.idl +++ b/Libraries/LibWeb/SVG/SVGFEBlendElement.idl @@ -27,7 +27,7 @@ interface SVGFEBlendElement : SVGElement { readonly attribute SVGAnimatedString in1; readonly attribute SVGAnimatedString in2; - readonly attribute SVGAnimatedEnumeration mode; + [ImplementedAs=mode_for_bindings] readonly attribute SVGAnimatedEnumeration mode; }; SVGFEBlendElement includes SVGFilterPrimitiveStandardAttributes; diff --git a/Libraries/LibWeb/SVG/SVGFilterElement.cpp b/Libraries/LibWeb/SVG/SVGFilterElement.cpp index 1e0d4985f4d..6dc72a0086c 100644 --- a/Libraries/LibWeb/SVG/SVGFilterElement.cpp +++ b/Libraries/LibWeb/SVG/SVGFilterElement.cpp @@ -118,8 +118,7 @@ Optional SVGFilterElement::gfx_filter() auto foreground = resolve_input_filter(blend_primitive->in1()->base_val()); auto background = resolve_input_filter(blend_primitive->in2()->base_val()); - // FIXME: Actually resolve the blend mode - auto blend_mode = Gfx::CompositingAndBlendingOperator::Normal; + auto blend_mode = blend_primitive.mode(); root_filter = Gfx::Filter::blend(background, foreground, blend_mode); update_result_map(*blend_primitive); diff --git a/Tests/LibWeb/Ref/expected/svg/blend-filter-ref.html b/Tests/LibWeb/Ref/expected/svg/blend-filter-ref.html new file mode 100644 index 00000000000..45fdd52f57c --- /dev/null +++ b/Tests/LibWeb/Ref/expected/svg/blend-filter-ref.html @@ -0,0 +1,5 @@ + + + + + diff --git a/Tests/LibWeb/Ref/input/svg/blend-filter.html b/Tests/LibWeb/Ref/input/svg/blend-filter.html new file mode 100644 index 00000000000..77fa8dfa1e4 --- /dev/null +++ b/Tests/LibWeb/Ref/input/svg/blend-filter.html @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/Tests/LibWeb/Text/expected/wpt-import/css/filter-effects/svgfeblendelement-mode-001.txt b/Tests/LibWeb/Text/expected/wpt-import/css/filter-effects/svgfeblendelement-mode-001.txt new file mode 100644 index 00000000000..786ef163f47 --- /dev/null +++ b/Tests/LibWeb/Text/expected/wpt-import/css/filter-effects/svgfeblendelement-mode-001.txt @@ -0,0 +1,41 @@ +Harness status: OK + +Found 35 tests + +18 Pass +17 Fail +Pass SVGFEBlendElement.prototype.mode, getter, initial value +Pass SVGFEBlendElement.prototype.mode, getter, invalid value +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "normal" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "multiply" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "screen" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "darken" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "lighten" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "overlay" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "color-dodge" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "color-burn" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "hard-light" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "soft-light" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "difference" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "exclusion" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "hue" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "saturation" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "color" +Pass SVGFEBlendElement.prototype.mode, getter, numeric value for "luminosity" +Fail SVGFEBlendElement.prototype.mode, setter, invalid value +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "normal" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "multiply" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "screen" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "darken" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "lighten" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "overlay" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "color-dodge" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "color-burn" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "hard-light" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "soft-light" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "difference" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "exclusion" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "hue" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "saturation" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "color" +Fail SVGFEBlendElement.prototype.mode, setter, numeric value for "luminosity" \ No newline at end of file diff --git a/Tests/LibWeb/Text/input/wpt-import/css/filter-effects/svgfeblendelement-mode-001.html b/Tests/LibWeb/Text/input/wpt-import/css/filter-effects/svgfeblendelement-mode-001.html new file mode 100644 index 00000000000..156c37dad4d --- /dev/null +++ b/Tests/LibWeb/Text/input/wpt-import/css/filter-effects/svgfeblendelement-mode-001.html @@ -0,0 +1,82 @@ + +SVGFEBlendElement.prototype.mode + + + + +