1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 11:27:35 +00:00

LibWeb: Expose SVG length/coordinate parsing methods

This is all still quite ad-hoc. Eventually these will both need to
support units (like with CSS Lengths) but for now we can continue only
using numbers.
This commit is contained in:
Sam Atkins 2022-02-11 15:48:42 +00:00 committed by Andreas Kling
parent 82308fb71a
commit 9424c67ed5
2 changed files with 57 additions and 1 deletions

View file

@ -26,6 +26,44 @@ Vector<PathInstruction> AttributeParser::parse_path_data()
return m_instructions; return m_instructions;
} }
Optional<float> AttributeParser::parse_coordinate(StringView input)
{
AttributeParser parser { input };
parser.parse_whitespace();
if (parser.match_coordinate()) {
float result = parser.parse_coordinate();
parser.parse_whitespace();
if (parser.done())
return result;
}
return {};
}
Optional<float> AttributeParser::parse_length(StringView input)
{
AttributeParser parser { input };
parser.parse_whitespace();
if (parser.match_coordinate()) {
float result = parser.parse_length();
parser.parse_whitespace();
if (parser.done())
return result;
}
return {};
}
Optional<float> AttributeParser::parse_positive_length(StringView input)
{
// FIXME: Where this is used, the spec usually (always?) says "A negative value is an error (see Error processing)."
// So, implement error processing! Maybe this should return ErrorOr.
auto result = parse_length(input);
if (result.has_value() && result.value() < 0)
result.clear();
return result;
}
void AttributeParser::parse_drawto() void AttributeParser::parse_drawto()
{ {
if (match('M') || match('m')) { if (match('M') || match('m')) {
@ -161,11 +199,18 @@ void AttributeParser::parse_elliptical_arc()
} }
} }
float AttributeParser::parse_coordinate() float AttributeParser::parse_length()
{ {
return parse_sign() * parse_number(); return parse_sign() * parse_number();
} }
float AttributeParser::parse_coordinate()
{
// https://www.w3.org/TR/SVG11/types.html#DataTypeCoordinate
// coordinate ::= length
return parse_length();
}
Vector<float> AttributeParser::parse_coordinate_pair() Vector<float> AttributeParser::parse_coordinate_pair()
{ {
Vector<float> coordinates; Vector<float> coordinates;
@ -360,6 +405,11 @@ bool AttributeParser::match_comma_whitespace() const
} }
bool AttributeParser::match_coordinate() const bool AttributeParser::match_coordinate() const
{
return match_length();
}
bool AttributeParser::match_length() const
{ {
return !done() && (isdigit(ch()) || ch() == '-' || ch() == '+' || ch() == '.'); return !done() && (isdigit(ch()) || ch() == '-' || ch() == '+' || ch() == '.');
} }

View file

@ -39,6 +39,10 @@ public:
Vector<PathInstruction> parse_path_data(); Vector<PathInstruction> parse_path_data();
static Optional<float> parse_coordinate(StringView input);
static Optional<float> parse_length(StringView input);
static Optional<float> parse_positive_length(StringView input);
private: private:
void parse_drawto(); void parse_drawto();
@ -53,6 +57,7 @@ private:
void parse_smooth_quadratic_bezier_curveto(); void parse_smooth_quadratic_bezier_curveto();
void parse_elliptical_arc(); void parse_elliptical_arc();
float parse_length();
float parse_coordinate(); float parse_coordinate();
Vector<float> parse_coordinate_pair(); Vector<float> parse_coordinate_pair();
Vector<float> parse_coordinate_sequence(); Vector<float> parse_coordinate_sequence();
@ -71,6 +76,7 @@ private:
bool match_whitespace() const; bool match_whitespace() const;
bool match_comma_whitespace() const; bool match_comma_whitespace() const;
bool match_coordinate() const; bool match_coordinate() const;
bool match_length() const;
bool match(char c) const { return !done() && ch() == c; } bool match(char c) const { return !done() && ch() == c; }
bool done() const { return m_cursor >= m_source.length(); } bool done() const { return m_cursor >= m_source.length(); }