Browse Source

Merge pull request #1682 from Gillibald/fixes/PathMarkupParser

Fix PathMarkupParser
pull/1673/merge
Jumar Macato 8 years ago
committed by GitHub
parent
commit
a62a7be0d5
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 52
      src/Avalonia.Visuals/Media/PathMarkupParser.cs
  2. 16
      tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs

52
src/Avalonia.Visuals/Media/PathMarkupParser.cs

@ -82,7 +82,8 @@ namespace Avalonia.Media
/// <param name="pathData">The path data.</param>
public void Parse(string pathData)
{
var tokens = ParseTokens(pathData);
var normalizedPathData = NormalizeWhiteSpaces(pathData);
var tokens = ParseTokens(normalizedPathData);
CreateGeometry(tokens);
}
@ -107,6 +108,45 @@ 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 +163,9 @@ namespace Avalonia.Media
private static IEnumerable<CommandToken> 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 +177,7 @@ namespace Avalonia.Media
private void CreateGeometry(IEnumerable<CommandToken> commandTokens)
{
_currentPoint = new Point();
_currentPoint = new Point();
foreach (var commandToken in commandTokens)
{
@ -468,7 +510,7 @@ namespace Avalonia.Media
private List<string> Arguments { get; }
public static CommandToken Parse(string s)
{
{
using (var reader = new StringReader(s))
{
var command = Command.None;
@ -590,7 +632,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)
{

16
tests/Avalonia.Visuals.UnitTests/Media/PathMarkupParserTests.cs

@ -7,6 +7,8 @@ using Xunit;
namespace Avalonia.Visuals.UnitTests.Media
{
using System.IO;
public class PathMarkupParserTests
{
[Fact]
@ -140,6 +142,7 @@ namespace Avalonia.Visuals.UnitTests.Media
}
[Theory]
[InlineData(" M0 0")]
[InlineData("F1 M24,14 A2,2,0,1,1,20,14 A2,2,0,1,1,24,14 z")] // issue #1107
[InlineData("M0 0L10 10z")]
[InlineData("M50 50 L100 100 L150 50")]
@ -173,5 +176,18 @@ namespace Avalonia.Visuals.UnitTests.Media
Assert.True(true);
}
}
[Theory]
[InlineData("0 0")]
[InlineData("j")]
public void Throws_InvalidDataException_On_None_Defined_Command(string pathData)
{
var pathGeometry = new PathGeometry();
using (var context = new PathGeometryContext(pathGeometry))
using (var parser = new PathMarkupParser(context))
{
Assert.Throws<InvalidDataException>(() => parser.Parse(pathData));
}
}
}
}
Loading…
Cancel
Save