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:
parent
82308fb71a
commit
9424c67ed5
2 changed files with 57 additions and 1 deletions
|
@ -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() == '.');
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(); }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue