LibWeb/SVG: Add FEFloodElement

This commit is contained in:
Lucien Fiorini 2025-07-06 21:48:55 +02:00 committed by Sam Atkins
commit d3684a36b0
Notes: github-actions[bot] 2025-07-09 17:08:44 +00:00
22 changed files with 189 additions and 18 deletions

View file

@ -823,6 +823,7 @@ set(SOURCES
SVG/SVGDescElement.cpp
SVG/SVGElement.cpp
SVG/SVGEllipseElement.cpp
SVG/SVGFEFloodElement.cpp
SVG/SVGFilterElement.cpp
SVG/SVGForeignObjectElement.cpp
SVG/SVGGElement.cpp

View file

@ -443,6 +443,22 @@ ClipRule ComputedProperties::clip_rule() const
return keyword_to_fill_rule(value.to_keyword()).release_value();
}
Color ComputedProperties::flood_color(Layout::NodeWithStyle const& node) const
{
auto const& value = property(PropertyID::FloodColor);
if (value.has_color()) {
return value.to_color(node, { .length_resolution_context = Length::ResolutionContext::for_layout_node(node) });
}
return InitialValues::flood_color();
}
float ComputedProperties::flood_opacity() const
{
auto const& value = property(PropertyID::FloodOpacity);
return resolve_opacity_value(value);
}
FlexDirection ComputedProperties::flex_direction() const
{
auto const& value = property(PropertyID::FlexDirection);

View file

@ -194,6 +194,8 @@ public:
float stroke_opacity() const;
FillRule fill_rule() const;
ClipRule clip_rule() const;
Color flood_color(Layout::NodeWithStyle const&) const;
float flood_opacity() const;
Gfx::FontCascadeList const& computed_font_list() const
{

View file

@ -152,6 +152,8 @@ public:
static float fill_opacity() { return 1.0f; }
static CSS::FillRule fill_rule() { return CSS::FillRule::Nonzero; }
static CSS::ClipRule clip_rule() { return CSS::ClipRule::Nonzero; }
static Color flood_color() { return Color::Black; }
static float flood_opacity() { return 1.0f; }
static CSS::LengthPercentage stroke_dashoffset() { return CSS::Length::make_px(0); }
static CSS::StrokeLinecap stroke_linecap() { return CSS::StrokeLinecap::Butt; }
static CSS::StrokeLinejoin stroke_linejoin() { return CSS::StrokeLinejoin::Miter; }
@ -554,6 +556,8 @@ public:
CSS::MaskType mask_type() const { return m_noninherited.mask_type; }
Optional<ClipPathReference> const& clip_path() const { return m_noninherited.clip_path; }
CSS::ClipRule clip_rule() const { return m_inherited.clip_rule; }
Color flood_color() const { return m_noninherited.flood_color; }
float flood_opacity() const { return m_noninherited.flood_opacity; }
LengthPercentage const& cx() const { return m_noninherited.cx; }
LengthPercentage const& cy() const { return m_noninherited.cy; }
@ -796,6 +800,9 @@ protected:
Vector<CounterData, 0> counter_increment;
Vector<CounterData, 0> counter_reset;
Vector<CounterData, 0> counter_set;
Color flood_color { InitialValues::flood_color() };
float flood_opacity { InitialValues::flood_opacity() };
} m_noninherited;
};
@ -982,6 +989,8 @@ public:
void set_mask_image(CSS::AbstractImageStyleValue const& value) { m_noninherited.mask_image = value; }
void set_clip_path(ClipPathReference value) { m_noninherited.clip_path = move(value); }
void set_clip_rule(CSS::ClipRule value) { m_inherited.clip_rule = value; }
void set_flood_color(Color value) { m_noninherited.flood_color = value; }
void set_flood_opacity(float value) { m_noninherited.flood_opacity = value; }
void set_cx(LengthPercentage cx) { m_noninherited.cx = move(cx); }
void set_cy(LengthPercentage cy) { m_noninherited.cy = move(cy); }

View file

@ -1537,6 +1537,24 @@
"float"
]
},
"flood-color": {
"affects-layout": false,
"animation-type": "by-computed-value",
"inherited": false,
"initial": "black",
"valid-types": [
"color"
]
},
"flood-opacity": {
"affects-layout": false,
"animation-type": "by-computed-value",
"inherited": false,
"initial": "1",
"valid-types": [
"number [0,1]"
]
},
"font": {
"inherited": true,
"initial": "normal medium serif",

View file

@ -91,6 +91,7 @@
#include <LibWeb/SVG/SVGDefsElement.h>
#include <LibWeb/SVG/SVGDescElement.h>
#include <LibWeb/SVG/SVGEllipseElement.h>
#include <LibWeb/SVG/SVGFEFloodElement.h>
#include <LibWeb/SVG/SVGFilterElement.h>
#include <LibWeb/SVG/SVGForeignObjectElement.h>
#include <LibWeb/SVG/SVGGElement.h>
@ -461,6 +462,8 @@ static GC::Ref<SVG::SVGElement> create_svg_element(JS::Realm& realm, Document& d
return realm.create<SVG::SVGDescElement>(document, move(qualified_name));
if (local_name == SVG::TagNames::ellipse)
return realm.create<SVG::SVGEllipseElement>(document, move(qualified_name));
if (local_name == SVG::TagNames::feFlood)
return realm.create<SVG::SVGFEFloodElement>(document, move(qualified_name));
if (local_name == SVG::TagNames::filter)
return realm.create<SVG::SVGFilterElement>(document, move(qualified_name));
if (local_name.equals_ignoring_ascii_case(SVG::TagNames::foreignObject))

View file

@ -967,6 +967,7 @@ class SVGDefsElement;
class SVGDescElement;
class SVGElement;
class SVGEllipseElement;
class SVGFEFloodElement;
class SVGFilterElement;
class SVGForeignObjectElement;
class SVGGeometryElement;

View file

@ -61,6 +61,9 @@ static ReadonlySpan<NamedPropertyID> attribute_style_properties()
NamedPropertyID(CSS::PropertyID::Display),
NamedPropertyID(CSS::PropertyID::FillOpacity),
NamedPropertyID(CSS::PropertyID::FillRule),
NamedPropertyID(CSS::PropertyID::Filter),
NamedPropertyID(CSS::PropertyID::FloodColor),
NamedPropertyID(CSS::PropertyID::FloodOpacity),
NamedPropertyID(CSS::PropertyID::FontFamily),
NamedPropertyID(CSS::PropertyID::FontSize),
NamedPropertyID(CSS::PropertyID::FontStyle),

View file

@ -29,6 +29,8 @@ public:
bool should_include_in_accessibility_tree() const;
virtual Optional<ARIA::Role> default_role() const override;
GC::Ref<SVGAnimatedLength> svg_animated_length_for_property(CSS::PropertyID) const;
virtual bool is_presentational_hint(FlyString const&) const override;
virtual void apply_presentational_hints(GC::Ref<CSS::CascadedProperties>) const override;
@ -47,8 +49,6 @@ protected:
void update_use_elements_that_reference_this();
void remove_from_use_element_that_reference_this();
GC::Ref<SVGAnimatedLength> svg_animated_length_for_property(CSS::PropertyID) const;
private:
// ^HTML::GlobalEventHandlers
virtual GC::Ptr<DOM::EventTarget> global_event_handlers_to_event_target(FlyString const&) override { return *this; }

View file

@ -0,0 +1,54 @@
/*
* Copyright (c) 2025, Lucien Fiorini <lucienfiorini@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/Bindings/SVGFEFloodElementPrototype.h>
#include <LibWeb/CSS/ComputedProperties.h>
#include <LibWeb/CSS/Parser/Parser.h>
#include <LibWeb/Layout/Node.h>
#include <LibWeb/Layout/SVGGraphicsBox.h>
#include <LibWeb/SVG/SVGFEFloodElement.h>
namespace Web::SVG {
GC_DEFINE_ALLOCATOR(SVGFEFloodElement);
SVGFEFloodElement::SVGFEFloodElement(DOM::Document& document, DOM::QualifiedName qualified_name)
: SVGElement(document, qualified_name)
{
}
void SVGFEFloodElement::initialize(JS::Realm& realm)
{
Base::initialize(realm);
WEB_SET_PROTOTYPE_FOR_INTERFACE(SVGFEFloodElement);
}
void SVGFEFloodElement::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
SVGFilterPrimitiveStandardAttributes::visit_edges(visitor);
}
GC::Ptr<Layout::Node> SVGFEFloodElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style)
{
return heap().allocate<Layout::SVGBox>(document(), *this, move(style));
}
// https://www.w3.org/TR/filter-effects-1/#FloodColorProperty
Gfx::Color SVGFEFloodElement::flood_color() const
{
// FIXME: Find a way to get the Gfx::Color of the flood_color property
// without having a layout node.
return Color::Black;
}
// https://www.w3.org/TR/filter-effects-1/#FloodOpacityProperty
float SVGFEFloodElement::flood_opacity() const
{
return computed_properties()->flood_opacity();
}
}

View file

@ -0,0 +1,36 @@
/*
* Copyright (c) 2025, Lucien Fiorini <lucienfiorini@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/SVG/SVGAnimatedLength.h>
#include <LibWeb/SVG/SVGElement.h>
#include <LibWeb/SVG/SVGFilterPrimitiveStandardAttributes.h>
namespace Web::SVG {
class SVGFEFloodElement final
: public SVGElement
, public SVGFilterPrimitiveStandardAttributes<SVGFEFloodElement> {
WEB_PLATFORM_OBJECT(SVGFEFloodElement, SVGElement);
GC_DECLARE_ALLOCATOR(SVGFEFloodElement);
public:
virtual ~SVGFEFloodElement() override = default;
virtual GC::Ptr<Layout::Node> create_layout_node(GC::Ref<CSS::ComputedProperties>) override;
Gfx::Color flood_color() const;
float flood_opacity() const;
private:
SVGFEFloodElement(DOM::Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
};
}

View file

@ -0,0 +1,8 @@
#import <SVG/SVGFilterPrimitiveStandardAttributes.idl>
// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGFEFloodElement
[Exposed=Window]
interface SVGFEFloodElement : SVGElement {
};
SVGFEFloodElement includes SVGFilterPrimitiveStandardAttributes;

View file

@ -17,6 +17,7 @@ namespace Web::SVG::TagNames {
__ENUMERATE_SVG_TAG(defs) \
__ENUMERATE_SVG_TAG(desc) \
__ENUMERATE_SVG_TAG(ellipse) \
__ENUMERATE_SVG_TAG(feFlood) \
__ENUMERATE_SVG_TAG(filter) \
__ENUMERATE_SVG_TAG(foreignObject) \
__ENUMERATE_SVG_TAG(g) \

View file

@ -340,6 +340,7 @@ libweb_js_bindings(SVG/SVGGraphicsElement)
libweb_js_bindings(SVG/SVGImageElement)
libweb_js_bindings(SVG/SVGCircleElement)
libweb_js_bindings(SVG/SVGEllipseElement)
libweb_js_bindings(SVG/SVGFEFloodElement)
libweb_js_bindings(SVG/SVGFilterElement)
libweb_js_bindings(SVG/SVGForeignObjectElement)
libweb_js_bindings(SVG/SVGLength)

View file

@ -338,6 +338,7 @@ SVGDefsElement
SVGDescElement
SVGElement
SVGEllipseElement
SVGFEFloodElement
SVGFilterElement
SVGForeignObjectElement
SVGGElement

View file

@ -155,6 +155,8 @@ All properties associated with getComputedStyle(document.body):
"flex-shrink",
"flex-wrap",
"float",
"flood-color",
"flood-opacity",
"grid-auto-columns",
"grid-auto-flow",
"grid-auto-rows",

View file

@ -385,6 +385,10 @@ All supported properties and their default values exposed from CSSStylePropertie
'flexWrap': 'nowrap'
'flex-wrap': 'nowrap'
'float': 'none'
'floodColor': 'rgb(0, 0, 0)'
'flood-color': 'rgb(0, 0, 0)'
'floodOpacity': '1'
'flood-opacity': '1'
'font': '16px serif'
'fontFamily': 'serif'
'font-family': 'serif'

View file

@ -153,6 +153,8 @@ flex-grow: 0
flex-shrink: 1
flex-wrap: nowrap
float: none
flood-color: rgb(0, 0, 0)
flood-opacity: 1
grid-auto-columns: auto
grid-auto-flow: row
grid-auto-rows: auto
@ -163,7 +165,7 @@ grid-row-start: auto
grid-template-areas: none
grid-template-columns: none
grid-template-rows: none
height: 2475px
height: 2505px
inline-size: 784px
inset-block-end: auto
inset-block-start: auto

View file

@ -1,9 +1,9 @@
Harness status: OK
Found 245 tests
Found 248 tests
239 Pass
6 Fail
241 Pass
7 Fail
Pass accent-color
Pass border-collapse
Pass border-spacing
@ -147,12 +147,15 @@ Pass counter-set
Pass cx
Pass cy
Pass display
Fail filter
Pass flex-basis
Pass flex-direction
Pass flex-grow
Pass flex-shrink
Pass flex-wrap
Pass float
Pass flood-color
Pass flood-opacity
Pass grid-auto-columns
Pass grid-auto-flow
Pass grid-auto-rows

View file

@ -1,9 +1,9 @@
Harness status: OK
Found 43 tests
Found 45 tests
39 Pass
4 Fail
42 Pass
3 Fail
Pass clip-path presentation attribute supported on an irrelevant element
Pass clip-rule presentation attribute supported on an irrelevant element
Pass color presentation attribute supported on an irrelevant element
@ -13,7 +13,9 @@ Pass display presentation attribute supported on an irrelevant element
Pass fill presentation attribute supported on an irrelevant element
Pass fill-opacity presentation attribute supported on an irrelevant element
Pass fill-rule presentation attribute supported on an irrelevant element
Fail filter presentation attribute supported on an irrelevant element
Pass filter presentation attribute supported on an irrelevant element
Pass flood-color presentation attribute supported on an irrelevant element
Pass flood-opacity presentation attribute supported on an irrelevant element
Pass font-family presentation attribute supported on an irrelevant element
Pass font-size presentation attribute supported on an irrelevant element
Fail font-stretch presentation attribute supported on an irrelevant element

View file

@ -1,9 +1,9 @@
Harness status: OK
Found 53 tests
Found 55 tests
48 Pass
5 Fail
51 Pass
4 Fail
Pass clip-path presentation attribute supported on a relevant element
Pass clip-rule presentation attribute supported on a relevant element
Pass color presentation attribute supported on a relevant element
@ -15,7 +15,9 @@ Pass display presentation attribute supported on a relevant element
Pass fill presentation attribute supported on a relevant element
Pass fill-opacity presentation attribute supported on a relevant element
Pass fill-rule presentation attribute supported on a relevant element
Fail filter presentation attribute supported on a relevant element
Pass filter presentation attribute supported on a relevant element
Pass flood-color presentation attribute supported on a relevant element
Pass flood-opacity presentation attribute supported on a relevant element
Pass font-family presentation attribute supported on a relevant element
Pass font-size presentation attribute supported on a relevant element
Fail font-stretch presentation attribute supported on a relevant element

View file

@ -1,9 +1,9 @@
Harness status: OK
Found 43 tests
Found 45 tests
39 Pass
4 Fail
42 Pass
3 Fail
Pass clip-path presentation attribute supported on an unknown SVG element
Pass clip-rule presentation attribute supported on an unknown SVG element
Pass color presentation attribute supported on an unknown SVG element
@ -13,7 +13,9 @@ Pass display presentation attribute supported on an unknown SVG element
Pass fill presentation attribute supported on an unknown SVG element
Pass fill-opacity presentation attribute supported on an unknown SVG element
Pass fill-rule presentation attribute supported on an unknown SVG element
Fail filter presentation attribute supported on an unknown SVG element
Pass filter presentation attribute supported on an unknown SVG element
Pass flood-color presentation attribute supported on an unknown SVG element
Pass flood-opacity presentation attribute supported on an unknown SVG element
Pass font-family presentation attribute supported on an unknown SVG element
Pass font-size presentation attribute supported on an unknown SVG element
Fail font-stretch presentation attribute supported on an unknown SVG element