1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 11:08:11 +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;
}
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()
{
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();
}
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> coordinates;
@ -360,6 +405,11 @@ bool AttributeParser::match_comma_whitespace() const
}
bool AttributeParser::match_coordinate() const
{
return match_length();
}
bool AttributeParser::match_length() const
{
return !done() && (isdigit(ch()) || ch() == '-' || ch() == '+' || ch() == '.');
}