mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Add SVGComponentTransferFunctionElement
This will be the base for <feFuncR>, <feFuncG>, <feFuncB> and <feFuncA>.
This commit is contained in:
parent
03a8de566b
commit
db321cb74f
Notes:
github-actions[bot]
2025-11-09 00:23:58 +00:00
Author: https://github.com/gmta
Commit: db321cb74f
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6709
10 changed files with 262 additions and 0 deletions
|
|
@ -907,6 +907,7 @@ set(SOURCES
|
|||
SVG/SVGAnimationElement.cpp
|
||||
SVG/SVGCircleElement.cpp
|
||||
SVG/SVGClipPathElement.cpp
|
||||
SVG/SVGComponentTransferFunctionElement.cpp
|
||||
SVG/SVGDecodedImageData.cpp
|
||||
SVG/SVGDefsElement.cpp
|
||||
SVG/SVGDescElement.cpp
|
||||
|
|
|
|||
|
|
@ -1098,6 +1098,7 @@ class SVGAnimatedRect;
|
|||
class SVGAnimationElement;
|
||||
class SVGCircleElement;
|
||||
class SVGClipPathElement;
|
||||
class SVGComponentTransferFunctionElement;
|
||||
class SVGDecodedImageData;
|
||||
class SVGDefsElement;
|
||||
class SVGDescElement;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2021-2023, Andreas Kling <andreas@ladybird.org>
|
||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
|
@ -11,6 +12,7 @@
|
|||
namespace Web::SVG::AttributeNames {
|
||||
|
||||
#define ENUMERATE_SVG_ATTRIBUTES \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(amplitude, "amplitude") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(attributeName, "attributeName") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(attributeType, "attributeType") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(baseFrequency, "baseFrequency") \
|
||||
|
|
@ -28,6 +30,7 @@ namespace Web::SVG::AttributeNames {
|
|||
__ENUMERATE_SVG_ATTRIBUTE(dy, "dy") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(edgeMode, "edgeMode") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(fill, "fill") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(exponent, "exponent") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(filterUnits, "filterUnits") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(fr, "fr") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(fx, "fx") \
|
||||
|
|
@ -39,6 +42,7 @@ namespace Web::SVG::AttributeNames {
|
|||
__ENUMERATE_SVG_ATTRIBUTE(href, "href") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(in, "in") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(in2, "in2") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(intercept, "intercept") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(kernelMatrix, "kernelMatrix") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(kernelUnitLength, "kernelUnitLength") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(k1, "k1") \
|
||||
|
|
@ -81,6 +85,7 @@ namespace Web::SVG::AttributeNames {
|
|||
__ENUMERATE_SVG_ATTRIBUTE(result, "result") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(rx, "rx") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(ry, "ry") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(slope, "slope") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(specularConstant, "specularConstant") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(specularExponent, "specularExponent") \
|
||||
__ENUMERATE_SVG_ATTRIBUTE(spreadMethod, "spreadMethod") \
|
||||
|
|
|
|||
|
|
@ -560,6 +560,27 @@ Optional<SpreadMethod> AttributeParser::parse_spread_method(StringView input)
|
|||
return {};
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-tablevalues
|
||||
Vector<float> AttributeParser::parse_table_values(StringView input)
|
||||
{
|
||||
Vector<float> table_values;
|
||||
|
||||
AttributeParser parser { input };
|
||||
while (!parser.done()) {
|
||||
parser.parse_whitespace();
|
||||
auto table_value = parser.parse_nonnegative_number();
|
||||
if (table_value.is_error())
|
||||
return {};
|
||||
|
||||
table_values.append(table_value.release_value());
|
||||
parser.parse_whitespace();
|
||||
if (parser.match(','))
|
||||
parser.consume();
|
||||
}
|
||||
|
||||
return table_values;
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/css-transforms/#svg-syntax
|
||||
Optional<Vector<Transform>> AttributeParser::parse_transform()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -148,6 +148,7 @@ public:
|
|||
static Optional<PreserveAspectRatio> parse_preserve_aspect_ratio(StringView input);
|
||||
static Optional<SVGUnits> parse_units(StringView input);
|
||||
static Optional<SpreadMethod> parse_spread_method(StringView input);
|
||||
static Vector<float> parse_table_values(StringView);
|
||||
static Optional<ViewBox> parse_viewbox(StringView input);
|
||||
|
||||
private:
|
||||
|
|
|
|||
147
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.cpp
Normal file
147
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.cpp
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/SVGComponentTransferFunctionElementPrototype.h>
|
||||
#include <LibWeb/SVG/AttributeNames.h>
|
||||
#include <LibWeb/SVG/AttributeParser.h>
|
||||
#include <LibWeb/SVG/SVGComponentTransferFunctionElement.h>
|
||||
#include <LibWeb/SVG/SVGNumber.h>
|
||||
#include <LibWeb/SVG/SVGNumberList.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(DOM::Document& document, DOM::QualifiedName qualified_name)
|
||||
: SVGElement(document, move(qualified_name))
|
||||
{
|
||||
}
|
||||
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-type
|
||||
static SVGComponentTransferFunctionElement::Type parse_type(Optional<String> const& value)
|
||||
{
|
||||
if (value == "identity"sv)
|
||||
return SVGComponentTransferFunctionElement::Type::Identity;
|
||||
if (value == "table"sv)
|
||||
return SVGComponentTransferFunctionElement::Type::Table;
|
||||
if (value == "discrete"sv)
|
||||
return SVGComponentTransferFunctionElement::Type::Discrete;
|
||||
if (value == "linear"sv)
|
||||
return SVGComponentTransferFunctionElement::Type::Linear;
|
||||
if (value == "gamma"sv)
|
||||
return SVGComponentTransferFunctionElement::Type::Gamma;
|
||||
|
||||
return SVGComponentTransferFunctionElement::Type::Unknown;
|
||||
}
|
||||
|
||||
void SVGComponentTransferFunctionElement::attribute_changed(FlyString const& name, Optional<String> const& old_value,
|
||||
Optional<String> const& value, Optional<FlyString> const& namespace_)
|
||||
{
|
||||
Base::attribute_changed(name, old_value, value, namespace_);
|
||||
|
||||
// FIXME: Support reflection instead of invalidating the enumeration.
|
||||
if (name == AttributeNames::type)
|
||||
m_type = {};
|
||||
|
||||
// FIXME: Support reflection instead of invalidating the list.
|
||||
if (name == AttributeNames::tableValues)
|
||||
m_table_values = {};
|
||||
}
|
||||
|
||||
void SVGComponentTransferFunctionElement::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(SVGComponentTransferFunctionElement);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void SVGComponentTransferFunctionElement::visit_edges(Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_type);
|
||||
visitor.visit(m_table_values);
|
||||
visitor.visit(m_slope);
|
||||
visitor.visit(m_intercept);
|
||||
visitor.visit(m_amplitude);
|
||||
visitor.visit(m_exponent);
|
||||
visitor.visit(m_offset);
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-type
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-type
|
||||
GC::Ref<SVGAnimatedEnumeration> SVGComponentTransferFunctionElement::type()
|
||||
{
|
||||
if (!m_type)
|
||||
m_type = SVGAnimatedEnumeration::create(realm(), to_underlying(type_from_attribute()));
|
||||
return *m_type;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-tablevalues
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-tablevalues
|
||||
GC::Ref<SVGAnimatedNumberList> SVGComponentTransferFunctionElement::table_values()
|
||||
{
|
||||
if (!m_table_values) {
|
||||
auto numbers = AttributeParser::parse_table_values(get_attribute_value(AttributeNames::tableValues));
|
||||
|
||||
Vector<GC::Ref<SVGNumber>> items;
|
||||
items.ensure_capacity(numbers.size());
|
||||
for (auto number : numbers)
|
||||
items.unchecked_append(SVGNumber::create(realm(), number, SVGNumber::ReadOnly::Yes));
|
||||
|
||||
auto number_list = SVGNumberList::create(realm(), move(items), ReadOnlyList::Yes);
|
||||
m_table_values = SVGAnimatedNumberList::create(realm(), number_list);
|
||||
}
|
||||
return *m_table_values;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-slope
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-slope
|
||||
GC::Ref<SVGAnimatedNumber> SVGComponentTransferFunctionElement::slope()
|
||||
{
|
||||
if (!m_slope)
|
||||
m_slope = SVGAnimatedNumber::create(realm(), *this, DOM::QualifiedName { AttributeNames::slope, {}, {} }, 1.f);
|
||||
return *m_slope;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-intercept
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-intercept
|
||||
GC::Ref<SVGAnimatedNumber> SVGComponentTransferFunctionElement::intercept()
|
||||
{
|
||||
if (!m_intercept)
|
||||
m_intercept = SVGAnimatedNumber::create(realm(), *this, DOM::QualifiedName { AttributeNames::intercept, {}, {} }, 0.f);
|
||||
return *m_intercept;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-amplitude
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-amplitude
|
||||
GC::Ref<SVGAnimatedNumber> SVGComponentTransferFunctionElement::amplitude()
|
||||
{
|
||||
if (!m_amplitude)
|
||||
m_amplitude = SVGAnimatedNumber::create(realm(), *this, DOM::QualifiedName { AttributeNames::amplitude, {}, {} }, 1.f);
|
||||
return *m_amplitude;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-exponent
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-exponent
|
||||
GC::Ref<SVGAnimatedNumber> SVGComponentTransferFunctionElement::exponent()
|
||||
{
|
||||
if (!m_exponent)
|
||||
m_exponent = SVGAnimatedNumber::create(realm(), *this, DOM::QualifiedName { AttributeNames::exponent, {}, {} }, 1.f);
|
||||
return *m_exponent;
|
||||
}
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#dom-svgcomponenttransferfunctionelement-offset
|
||||
// https://drafts.fxtf.org/filter-effects-1/#element-attrdef-fecomponenttransfer-offset
|
||||
GC::Ref<SVGAnimatedNumber> SVGComponentTransferFunctionElement::offset()
|
||||
{
|
||||
if (!m_offset)
|
||||
m_offset = SVGAnimatedNumber::create(realm(), *this, DOM::QualifiedName { AttributeNames::offset, {}, {} }, 0.f);
|
||||
return *m_offset;
|
||||
}
|
||||
|
||||
SVGComponentTransferFunctionElement::Type SVGComponentTransferFunctionElement::type_from_attribute() const
|
||||
{
|
||||
return parse_type(get_attribute_value(AttributeNames::type));
|
||||
}
|
||||
|
||||
}
|
||||
62
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.h
Normal file
62
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/SVG/SVGAnimatedEnumeration.h>
|
||||
#include <LibWeb/SVG/SVGAnimatedNumber.h>
|
||||
#include <LibWeb/SVG/SVGAnimatedNumberList.h>
|
||||
#include <LibWeb/SVG/SVGElement.h>
|
||||
|
||||
namespace Web::SVG {
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGComponentTransferFunctionElement
|
||||
class SVGComponentTransferFunctionElement
|
||||
: public SVGElement {
|
||||
WEB_PLATFORM_OBJECT(SVGComponentTransferFunctionElement, SVGElement);
|
||||
|
||||
public:
|
||||
enum class Type : u8 {
|
||||
Unknown = 0,
|
||||
Identity = 1,
|
||||
Table = 2,
|
||||
Discrete = 3,
|
||||
Linear = 4,
|
||||
Gamma = 5,
|
||||
};
|
||||
|
||||
virtual ~SVGComponentTransferFunctionElement() override = default;
|
||||
|
||||
virtual void attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
|
||||
|
||||
GC::Ref<SVGAnimatedEnumeration> type();
|
||||
GC::Ref<SVGAnimatedNumberList> table_values();
|
||||
GC::Ref<SVGAnimatedNumber> slope();
|
||||
GC::Ref<SVGAnimatedNumber> intercept();
|
||||
GC::Ref<SVGAnimatedNumber> amplitude();
|
||||
GC::Ref<SVGAnimatedNumber> exponent();
|
||||
GC::Ref<SVGAnimatedNumber> offset();
|
||||
|
||||
protected:
|
||||
SVGComponentTransferFunctionElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
private:
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
Type type_from_attribute() const;
|
||||
|
||||
GC::Ptr<SVGAnimatedEnumeration> m_type;
|
||||
GC::Ptr<SVGAnimatedNumberList> m_table_values;
|
||||
GC::Ptr<SVGAnimatedNumber> m_slope;
|
||||
GC::Ptr<SVGAnimatedNumber> m_intercept;
|
||||
GC::Ptr<SVGAnimatedNumber> m_amplitude;
|
||||
GC::Ptr<SVGAnimatedNumber> m_exponent;
|
||||
GC::Ptr<SVGAnimatedNumber> m_offset;
|
||||
};
|
||||
|
||||
}
|
||||
22
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.idl
Normal file
22
Libraries/LibWeb/SVG/SVGComponentTransferFunctionElement.idl
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#import <SVG/SVGElement.idl>
|
||||
|
||||
// https://www.w3.org/TR/filter-effects-1/#InterfaceSVGComponentTransferFunctionElement
|
||||
[Exposed=Window]
|
||||
interface SVGComponentTransferFunctionElement : SVGElement {
|
||||
|
||||
// Component Transfer Types
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_UNKNOWN = 0;
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_IDENTITY = 1;
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_TABLE = 2;
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_DISCRETE = 3;
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_LINEAR = 4;
|
||||
const unsigned short SVG_FECOMPONENTTRANSFER_TYPE_GAMMA = 5;
|
||||
|
||||
readonly attribute SVGAnimatedEnumeration type;
|
||||
readonly attribute SVGAnimatedNumberList tableValues;
|
||||
readonly attribute SVGAnimatedNumber slope;
|
||||
readonly attribute SVGAnimatedNumber intercept;
|
||||
readonly attribute SVGAnimatedNumber amplitude;
|
||||
readonly attribute SVGAnimatedNumber exponent;
|
||||
readonly attribute SVGAnimatedNumber offset;
|
||||
};
|
||||
|
|
@ -378,6 +378,7 @@ libweb_js_bindings(SVG/SVGAnimatedString)
|
|||
libweb_js_bindings(SVG/SVGAnimatedTransformList)
|
||||
libweb_js_bindings(SVG/SVGAnimationElement)
|
||||
libweb_js_bindings(SVG/SVGClipPathElement)
|
||||
libweb_js_bindings(SVG/SVGComponentTransferFunctionElement)
|
||||
libweb_js_bindings(SVG/SVGDefsElement)
|
||||
libweb_js_bindings(SVG/SVGDescElement)
|
||||
libweb_js_bindings(SVG/SVGElement)
|
||||
|
|
|
|||
|
|
@ -372,6 +372,7 @@ SVGAnimatedTransformList
|
|||
SVGAnimationElement
|
||||
SVGCircleElement
|
||||
SVGClipPathElement
|
||||
SVGComponentTransferFunctionElement
|
||||
SVGDefsElement
|
||||
SVGDescElement
|
||||
SVGElement
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue