summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibWeb
diff options
context:
space:
mode:
authorSam Atkins <atkinssj@serenityos.org>2022-02-11 15:48:42 +0000
committerAndreas Kling <kling@serenityos.org>2022-02-11 21:38:27 +0100
commit9424c67ed5ce5d29eb96f90b1e48700c1a7dd6b5 (patch)
tree0512405cc1870e5ae5a1cf58f5436571f79b1e9b /Userland/Libraries/LibWeb
parent82308fb71a5ec3748a46c09d167bf29cfa187fe4 (diff)
downloadserenity-9424c67ed5ce5d29eb96f90b1e48700c1a7dd6b5.zip
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.
Diffstat (limited to 'Userland/Libraries/LibWeb')
-rw-r--r--Userland/Libraries/LibWeb/SVG/AttributeParser.cpp52
-rw-r--r--Userland/Libraries/LibWeb/SVG/AttributeParser.h6
2 files changed, 57 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/SVG/AttributeParser.cpp b/Userland/Libraries/LibWeb/SVG/AttributeParser.cpp
index cc68f80345..e6eb4c5d9d 100644
--- a/Userland/Libraries/LibWeb/SVG/AttributeParser.cpp
+++ b/Userland/Libraries/LibWeb/SVG/AttributeParser.cpp
@@ -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;
@@ -361,6 +406,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() == '.');
}
diff --git a/Userland/Libraries/LibWeb/SVG/AttributeParser.h b/Userland/Libraries/LibWeb/SVG/AttributeParser.h
index 61a2ca690d..6564b6baa3 100644
--- a/Userland/Libraries/LibWeb/SVG/AttributeParser.h
+++ b/Userland/Libraries/LibWeb/SVG/AttributeParser.h
@@ -39,6 +39,10 @@ public:
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:
void parse_drawto();
@@ -53,6 +57,7 @@ private:
void parse_smooth_quadratic_bezier_curveto();
void parse_elliptical_arc();
+ float parse_length();
float parse_coordinate();
Vector<float> parse_coordinate_pair();
Vector<float> parse_coordinate_sequence();
@@ -71,6 +76,7 @@ private:
bool match_whitespace() const;
bool match_comma_whitespace() const;
bool match_coordinate() const;
+ bool match_length() const;
bool match(char c) const { return !done() && ch() == c; }
bool done() const { return m_cursor >= m_source.length(); }