LibWeb: Add support for the SVG gradient spreadMethod attribute

This commit is contained in:
MacDue 2023-08-20 15:45:02 +01:00 committed by Andreas Kling
parent 1ecb2cf28c
commit 46f42d9755
Notes: sideshowbarker 2024-07-16 22:14:49 +09:00
6 changed files with 52 additions and 0 deletions

View file

@ -509,6 +509,21 @@ Optional<GradientUnits> AttributeParser::parse_gradient_units(StringView input)
return {};
}
// https://svgwg.org/svg2-draft/pservers.html#RadialGradientElementSpreadMethodAttribute
Optional<SpreadMethod> AttributeParser::parse_spread_method(StringView input)
{
GenericLexer lexer { input };
lexer.ignore_while(whitespace);
auto spread_method_string = lexer.consume_until(whitespace);
if (spread_method_string == "pad"sv)
return SpreadMethod::Pad;
if (spread_method_string == "repeat"sv)
return SpreadMethod::Repeat;
if (spread_method_string == "reflect"sv)
return SpreadMethod::Reflect;
return {};
}
// https://drafts.csswg.org/css-transforms/#svg-syntax
Optional<Vector<Transform>> AttributeParser::parse_transform()
{

View file

@ -93,6 +93,12 @@ enum class GradientUnits {
UserSpaceOnUse
};
enum class SpreadMethod {
Pad,
Repeat,
Reflect
};
class NumberPercentage {
public:
NumberPercentage(float value, bool is_percentage)
@ -144,6 +150,7 @@ public:
static Optional<Vector<Transform>> parse_transform(StringView input);
static Optional<PreserveAspectRatio> parse_preserve_aspect_ratio(StringView input);
static Optional<GradientUnits> parse_gradient_units(StringView input);
static Optional<SpreadMethod> parse_spread_method(StringView input);
private:
AttributeParser(StringView source);

View file

@ -22,6 +22,8 @@ void SVGGradientElement::attribute_changed(DeprecatedFlyString const& name, Depr
SVGElement::attribute_changed(name, value);
if (name == AttributeNames::gradientUnits) {
m_gradient_units = AttributeParser::parse_gradient_units(value);
} else if (name == AttributeNames::spreadMethod) {
m_spread_method = AttributeParser::parse_spread_method(value);
} else if (name == AttributeNames::gradientTransform) {
if (auto transform_list = AttributeParser::parse_transform(value); transform_list.has_value()) {
m_gradient_transform = transform_from_transform_list(*transform_list);
@ -40,6 +42,15 @@ GradientUnits SVGGradientElement::gradient_units() const
return GradientUnits::ObjectBoundingBox;
}
SpreadMethod SVGGradientElement::spread_method() const
{
if (m_spread_method.has_value())
return *m_spread_method;
if (auto gradient = linked_gradient())
return gradient->spread_method();
return SpreadMethod::Pad;
}
Optional<Gfx::AffineTransform> SVGGradientElement::gradient_transform() const
{
if (m_gradient_transform.has_value())

View file

@ -20,6 +20,20 @@ struct SVGPaintContext {
Gfx::AffineTransform transform;
};
inline Gfx::SVGGradientPaintStyle::SpreadMethod to_gfx_spread_method(SpreadMethod spread_method)
{
switch (spread_method) {
case SpreadMethod::Pad:
return Gfx::SVGGradientPaintStyle::SpreadMethod::Pad;
case SpreadMethod::Reflect:
return Gfx::SVGGradientPaintStyle::SpreadMethod::Reflect;
case SpreadMethod::Repeat:
return Gfx::SVGGradientPaintStyle::SpreadMethod::Repeat;
default:
VERIFY_NOT_REACHED();
}
}
class SVGGradientElement : public SVGElement {
WEB_PLATFORM_OBJECT(SVGGradientElement, SVGElement);
@ -32,6 +46,8 @@ public:
GradientUnits gradient_units() const;
SpreadMethod spread_method() const;
Optional<Gfx::AffineTransform> gradient_transform() const;
protected:
@ -61,6 +77,7 @@ protected:
private:
Optional<GradientUnits> m_gradient_units = {};
Optional<SpreadMethod> m_spread_method = {};
Optional<Gfx::AffineTransform> m_gradient_transform = {};
};

View file

@ -131,6 +131,7 @@ Optional<Gfx::PaintStyle const&> SVGLinearGradientElement::to_gfx_paint_style(SV
}
m_paint_style->set_gradient_transform(gradient_paint_transform(paint_context));
m_paint_style->set_spread_method(to_gfx_spread_method(spread_method()));
return *m_paint_style;
}

View file

@ -172,6 +172,7 @@ Optional<Gfx::PaintStyle const&> SVGRadialGradientElement::to_gfx_paint_style(SV
m_paint_style->set_end_radius(end_radius);
}
m_paint_style->set_gradient_transform(gradient_paint_transform(paint_context));
m_paint_style->set_spread_method(to_gfx_spread_method(spread_method()));
return *m_paint_style;
}