diff options
author | Sam Atkins <atkinssj@serenityos.org> | 2022-02-11 15:48:42 +0000 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-02-11 21:38:27 +0100 |
commit | 9424c67ed5ce5d29eb96f90b1e48700c1a7dd6b5 (patch) | |
tree | 0512405cc1870e5ae5a1cf58f5436571f79b1e9b /Userland/Libraries/LibWeb | |
parent | 82308fb71a5ec3748a46c09d167bf29cfa187fe4 (diff) | |
download | serenity-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.cpp | 52 | ||||
-rw-r--r-- | Userland/Libraries/LibWeb/SVG/AttributeParser.h | 6 |
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(); } |