LibWeb: Plumbing for svg stroke-dasharray

This commit is contained in:
Nico Weber 2024-11-20 19:23:10 -05:00 committed by Alexander Kalenik
commit 94b97aa365
Notes: github-actions[bot] 2024-11-21 17:57:47 +00:00
10 changed files with 277 additions and 172 deletions

View file

@ -480,6 +480,7 @@ public:
CSS::FillRule fill_rule() const { return m_inherited.fill_rule; }
Optional<SVGPaint> const& stroke() const { return m_inherited.stroke; }
float fill_opacity() const { return m_inherited.fill_opacity; }
Vector<Variant<LengthPercentage, NumberOrCalculated>> const& stroke_dasharray() const { return m_inherited.stroke_dasharray; }
LengthPercentage const& stroke_dashoffset() const { return m_inherited.stroke_dashoffset; }
CSS::StrokeLinecap stroke_linecap() const { return m_inherited.stroke_linecap; }
CSS::StrokeLinejoin stroke_linejoin() const { return m_inherited.stroke_linejoin; }
@ -581,6 +582,7 @@ protected:
CSS::FillRule fill_rule { InitialValues::fill_rule() };
Optional<SVGPaint> stroke;
float fill_opacity { InitialValues::fill_opacity() };
Vector<Variant<LengthPercentage, NumberOrCalculated>> stroke_dasharray;
LengthPercentage stroke_dashoffset { InitialValues::stroke_dashoffset() };
CSS::StrokeLinecap stroke_linecap { InitialValues::stroke_linecap() };
CSS::StrokeLinejoin stroke_linejoin { InitialValues::stroke_linejoin() };
@ -830,6 +832,7 @@ public:
void set_stroke(SVGPaint value) { m_inherited.stroke = value; }
void set_fill_rule(CSS::FillRule value) { m_inherited.fill_rule = value; }
void set_fill_opacity(float value) { m_inherited.fill_opacity = value; }
void set_stroke_dasharray(Vector<Variant<LengthPercentage, NumberOrCalculated>> value) { m_inherited.stroke_dasharray = move(value); }
void set_stroke_dashoffset(LengthPercentage value) { m_inherited.stroke_dashoffset = value; }
void set_stroke_linecap(CSS::StrokeLinecap value) { m_inherited.stroke_linecap = value; }
void set_stroke_linejoin(CSS::StrokeLinejoin value) { m_inherited.stroke_linejoin = value; }

View file

@ -5017,6 +5017,38 @@ RefPtr<CSSStyleValue> Parser::parse_rotate_value(TokenStream<ComponentValue>& to
return nullptr;
}
RefPtr<CSSStyleValue> Parser::parse_stroke_dasharray_value(TokenStream<ComponentValue>& tokens)
{
// https://svgwg.org/svg2-draft/painting.html#StrokeDashing
// Value: none | <dasharray>
if (auto none = parse_all_as_single_keyword_value(tokens, Keyword::None))
return none;
// https://svgwg.org/svg2-draft/painting.html#DataTypeDasharray
// <dasharray> = [ [ <length-percentage> | <number> ]+ ]#
Vector<ValueComparingNonnullRefPtr<CSSStyleValue const>> dashes;
while (tokens.has_next_token()) {
tokens.discard_whitespace();
// A <dasharray> is a list of comma and/or white space separated <number> or <length-percentage> values. A <number> value represents a value in user units.
auto value = parse_number_value(tokens);
if (value) {
dashes.append(value.release_nonnull());
} else {
auto value = parse_length_percentage_value(tokens);
if (!value)
return {};
dashes.append(value.release_nonnull());
}
tokens.discard_whitespace();
if (tokens.has_next_token() && tokens.next_token().is(Token::Type::Comma))
tokens.discard_a_token();
}
return StyleValueList::create(move(dashes), StyleValueList::Separator::Comma);
}
RefPtr<CSSStyleValue> Parser::parse_content_value(TokenStream<ComponentValue>& tokens)
{
// FIXME: `content` accepts several kinds of function() type, which we don't handle in property_accepts_value() yet.
@ -7885,6 +7917,10 @@ Parser::ParseErrorOr<NonnullRefPtr<CSSStyleValue>> Parser::parse_css_value(Prope
if (auto parsed_value = parse_scrollbar_gutter_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::StrokeDasharray:
if (auto parsed_value = parse_stroke_dasharray_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();
return ParseError::SyntaxError;
case PropertyID::TextDecoration:
if (auto parsed_value = parse_text_decoration_value(tokens); parsed_value && !tokens.has_next_token())
return parsed_value.release_nonnull();

View file

@ -339,6 +339,7 @@ private:
RefPtr<CSSStyleValue> parse_text_decoration_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_text_decoration_line_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_rotate_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_stroke_dasharray_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_easing_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_transform_value(TokenStream<ComponentValue>&);
RefPtr<CSSStyleValue> parse_transform_origin_value(TokenStream<ComponentValue>&);

View file

@ -2420,6 +2420,12 @@
"paint"
]
},
"stroke-dasharray": {
"animation-type": "custom",
"inherited": true,
"initial": "none",
"affects-layout": false
},
"stroke-dashoffset": {
"affects-layout": false,
"animation-type": "by-computed-value",