diff --git a/src/Avalonia.Visuals/Media/PathMarkupParser.cs b/src/Avalonia.Visuals/Media/PathMarkupParser.cs index e8824753b5..46a4de637d 100644 --- a/src/Avalonia.Visuals/Media/PathMarkupParser.cs +++ b/src/Avalonia.Visuals/Media/PathMarkupParser.cs @@ -82,7 +82,9 @@ namespace Avalonia.Media /// The path data. public void Parse(string pathData) { - var tokens = ParseTokens(pathData); + var normalizedPathData = NormalizeWhiteSpaces(pathData); + + var tokens = ParseTokens(normalizedPathData); CreateGeometry(tokens); } @@ -107,6 +109,42 @@ namespace Avalonia.Media _isDisposed = true; } + private static string NormalizeWhiteSpaces(string s) + { + int length = s.Length, + index = 0, + i = 0; + var source = s.ToCharArray(); + var skip = false; + + for (; i < length; i++) + { + var c = source[i]; + + if (char.IsWhiteSpace(c)) + { + if (skip) + { + continue; + } + + source[index++] = c; + skip = true; + continue; + } + + skip = false; + source[index++] = c; + } + + if (char.IsWhiteSpace(source[index - 1])) + { + index--; + } + + return char.IsWhiteSpace(source[0]) ? new string(source, 1, index) : new string(source, 0, index); + } + private static string CreatesSeparatorPattern() { var stringBuilder = new StringBuilder(); @@ -123,7 +161,9 @@ namespace Avalonia.Media private static IEnumerable ParseTokens(string s) { - return Regex.Split(s, s_separatorPattern).Where(t => !string.IsNullOrEmpty(t)).Select(CommandToken.Parse); + var expressions = Regex.Split(s, s_separatorPattern).Where(t => !string.IsNullOrEmpty(t)); + + return expressions.Select(CommandToken.Parse); } private static Point MirrorControlPoint(Point controlPoint, Point center) @@ -135,7 +175,7 @@ namespace Avalonia.Media private void CreateGeometry(IEnumerable commandTokens) { - _currentPoint = new Point(); + _currentPoint = new Point(); foreach (var commandToken in commandTokens) { @@ -468,7 +508,7 @@ namespace Avalonia.Media private List Arguments { get; } public static CommandToken Parse(string s) - { + { using (var reader = new StringReader(s)) { var command = Command.None; @@ -590,7 +630,7 @@ namespace Avalonia.Media var y = ReadDouble(); return new Point(origin.X + x, origin.Y + y); - } + } private static bool ReadCommand(TextReader reader, ref Command command, ref bool relative) {