23 changed files with 666 additions and 73 deletions
@ -0,0 +1,27 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="GeometryImpl.cs" company="Tricycle">
|
|||
// Copyright 2014 Tricycle. All rights reserved.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Direct2D1.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using SharpDX.Direct2D1; |
|||
using Splat; |
|||
|
|||
public abstract class GeometryImpl : IGeometryImpl |
|||
{ |
|||
public abstract Rect Bounds |
|||
{ |
|||
get; |
|||
} |
|||
|
|||
public SharpDX.Direct2D1.Geometry Geometry |
|||
{ |
|||
get; |
|||
protected set; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,44 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Direct2D1StreamGeometryContext.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Direct2D1.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using SharpDX.Direct2D1; |
|||
using Splat; |
|||
|
|||
public class StreamGeometryContextImpl : IStreamGeometryContextImpl |
|||
{ |
|||
private GeometrySink sink; |
|||
|
|||
public StreamGeometryContextImpl(GeometrySink sink) |
|||
{ |
|||
this.sink = sink; |
|||
} |
|||
|
|||
public void BeginFigure(Point startPoint, bool isFilled) |
|||
{ |
|||
this.sink.BeginFigure(startPoint.ToSharpDX(), isFilled ? FigureBegin.Filled : FigureBegin.Hollow); |
|||
} |
|||
|
|||
public void LineTo(Point point) |
|||
{ |
|||
this.sink.AddLine(point.ToSharpDX()); |
|||
} |
|||
|
|||
public void EndFigure(bool isClosed) |
|||
{ |
|||
this.sink.EndFigure(isClosed ? FigureEnd.Closed : FigureEnd.Open); |
|||
} |
|||
|
|||
public void Dispose() |
|||
{ |
|||
this.sink.Close(); |
|||
this.sink.Dispose(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Direct2DStreamGeometry.cs" company="Tricycle">
|
|||
// Copyright 2014 Tricycle. All rights reserved.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Direct2D1.Media |
|||
{ |
|||
using System; |
|||
using Perspex.Media; |
|||
using SharpDX.Direct2D1; |
|||
using Splat; |
|||
|
|||
public class StreamGeometryImpl : GeometryImpl, IStreamGeometryImpl |
|||
{ |
|||
private PathGeometry geometry; |
|||
|
|||
public StreamGeometryImpl() |
|||
{ |
|||
Factory factory = Locator.Current.GetService<Factory>(); |
|||
this.geometry = new PathGeometry(factory); |
|||
this.Geometry = this.geometry; |
|||
} |
|||
|
|||
public override Rect Bounds |
|||
{ |
|||
get { return geometry.GetBounds().ToPerspex(); } |
|||
} |
|||
|
|||
public IStreamGeometryContextImpl Open() |
|||
{ |
|||
return new StreamGeometryContextImpl(geometry.Open()); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,28 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PrimitiveExtensions.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Direct2D1 |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using SharpDX; |
|||
|
|||
public static class PrimitiveExtensions |
|||
{ |
|||
public static Rect ToPerspex(this RectangleF r) |
|||
{ |
|||
return new Rect(r.X, r.Y, r.Width, r.Height); |
|||
} |
|||
|
|||
public static Vector2 ToSharpDX(this Perspex.Point p) |
|||
{ |
|||
return new Vector2((float)p.X, (float)p.Y); |
|||
} |
|||
} |
|||
} |
|||
@ -1,26 +0,0 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Direct2DStreamGeometry.cs" company="Tricycle">
|
|||
// Copyright 2014 Tricycle. All rights reserved.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Windows.Media |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Text; |
|||
using System.Threading.Tasks; |
|||
using Perspex.Media; |
|||
using SharpDX.Direct2D1; |
|||
|
|||
public class Direct2DStreamGeometry : IStreamGeometryImpl |
|||
{ |
|||
private PathGeometry geometry; |
|||
|
|||
public void Initalize(IStreamGeometryImpl impl) |
|||
{ |
|||
//this.geometry = new PathGeometry();
|
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,13 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="IGeometryImpl.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public interface IGeometryImpl |
|||
{ |
|||
Rect Bounds { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,291 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="PathMarkupParser.cs" company="Steven Kirk">
|
|||
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
using System.Text; |
|||
|
|||
public class PathMarkupParser |
|||
{ |
|||
private static readonly Dictionary<char, Command> Commands = new Dictionary<char, Command> |
|||
{ |
|||
{ 'F', Command.FillRule }, |
|||
{ 'f', Command.FillRule }, |
|||
{ 'M', Command.Move }, |
|||
{ 'm', Command.MoveRelative }, |
|||
{ 'L', Command.Line }, |
|||
{ 'l', Command.LineRelative }, |
|||
{ 'H', Command.HorizontalLine }, |
|||
{ 'h', Command.HorizontalLineRelative }, |
|||
{ 'V', Command.VerticalLine }, |
|||
{ 'v', Command.VerticalLineRelative }, |
|||
{ 'C', Command.CubicBezierCurve }, |
|||
{ 'c', Command.CubicBezierCurveRelative }, |
|||
{ 'Z', Command.Close }, |
|||
{ 'z', Command.Close }, |
|||
}; |
|||
|
|||
private StreamGeometry geometry; |
|||
|
|||
private StreamGeometryContext context; |
|||
|
|||
public PathMarkupParser(StreamGeometry geometry, StreamGeometryContext context) |
|||
{ |
|||
this.geometry = geometry; |
|||
this.context = context; |
|||
} |
|||
|
|||
private enum Command |
|||
{ |
|||
None, |
|||
FillRule, |
|||
Move, |
|||
MoveRelative, |
|||
Line, |
|||
LineRelative, |
|||
HorizontalLine, |
|||
HorizontalLineRelative, |
|||
VerticalLine, |
|||
VerticalLineRelative, |
|||
CubicBezierCurve, |
|||
CubicBezierCurveRelative, |
|||
Close, |
|||
Eof, |
|||
} |
|||
|
|||
public void Parse(string s) |
|||
{ |
|||
bool openFigure = false; |
|||
|
|||
using (StringReader reader = new StringReader(s)) |
|||
{ |
|||
Command lastCommand = Command.None; |
|||
Command command; |
|||
Point startPoint = new Point(); |
|||
Point point = new Point(); |
|||
|
|||
while ((command = ReadCommand(reader, lastCommand)) != Command.Eof) |
|||
{ |
|||
switch (command) |
|||
{ |
|||
case Command.FillRule: |
|||
// TODO: Implement.
|
|||
reader.Read(); |
|||
break; |
|||
|
|||
case Command.Move: |
|||
case Command.MoveRelative: |
|||
point = startPoint = ReadPoint(reader); |
|||
this.context.BeginFigure(point, true); |
|||
openFigure = true; |
|||
break; |
|||
|
|||
case Command.Line: |
|||
point = ReadPoint(reader); |
|||
this.context.LineTo(point); |
|||
break; |
|||
|
|||
case Command.LineRelative: |
|||
point = ReadRelativePoint(reader, point); |
|||
this.context.LineTo(point); |
|||
break; |
|||
|
|||
//case Command.HorizontalLine:
|
|||
// point.X = ReadDouble(reader);
|
|||
// this.context.LineTo(point, true, false);
|
|||
// break;
|
|||
|
|||
//case Command.HorizontalLineRelative:
|
|||
// point.X += ReadDouble(reader);
|
|||
// this.context.LineTo(point, true, false);
|
|||
// break;
|
|||
|
|||
//case Command.VerticalLine:
|
|||
// point.Y = ReadDouble(reader);
|
|||
// this.context.LineTo(point, true, false);
|
|||
// break;
|
|||
|
|||
//case Command.VerticalLineRelative:
|
|||
// point.Y += ReadDouble(reader);
|
|||
// this.context.LineTo(point, true, false);
|
|||
// break;
|
|||
|
|||
//case Command.CubicBezierCurve:
|
|||
//{
|
|||
// Point point1 = ReadPoint(reader);
|
|||
// Point point2 = ReadPoint(reader);
|
|||
// point = ReadPoint(reader);
|
|||
// this.context.BezierTo(point1, point2, point, true, false);
|
|||
// break;
|
|||
//}
|
|||
|
|||
case Command.Close: |
|||
this.context.EndFigure(true); |
|||
openFigure = false; |
|||
break; |
|||
|
|||
default: |
|||
throw new NotSupportedException("Unsupported command"); |
|||
} |
|||
|
|||
lastCommand = command; |
|||
} |
|||
|
|||
if (openFigure) |
|||
{ |
|||
this.context.EndFigure(true); |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static Command ReadCommand(StringReader reader, Command lastCommand) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
|
|||
int i = reader.Peek(); |
|||
|
|||
if (i == -1) |
|||
{ |
|||
return Command.Eof; |
|||
} |
|||
else |
|||
{ |
|||
char c = (char)i; |
|||
Command command = Command.None; |
|||
bool canMove = lastCommand == Command.None || lastCommand == Command.FillRule || lastCommand == Command.Close; |
|||
|
|||
if (!Commands.TryGetValue(c, out command)) |
|||
{ |
|||
if ((char.IsDigit(c) || c == '.' || c == '+' || c == '-') && |
|||
(lastCommand != Command.None)) |
|||
{ |
|||
return lastCommand; |
|||
} |
|||
else |
|||
{ |
|||
throw new InvalidDataException("Unexpected path command '" + c + "'."); |
|||
} |
|||
} |
|||
|
|||
if (!canMove && command <= Command.MoveRelative) |
|||
{ |
|||
command += 2; |
|||
} |
|||
|
|||
reader.Read(); |
|||
return command; |
|||
} |
|||
} |
|||
|
|||
private static double ReadDouble(TextReader reader) |
|||
{ |
|||
// TODO: Handle Infinity, NaN and scientific notation.
|
|||
StringBuilder b = new StringBuilder(); |
|||
bool readSign = false; |
|||
bool readPoint = false; |
|||
bool readExponent = false; |
|||
int i; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = char.ToUpperInvariant((char)i); |
|||
|
|||
if (((c == '+' || c == '-') && !readSign) || |
|||
(c == '.' && !readPoint) || |
|||
(c == 'E' && !readExponent) || |
|||
char.IsDigit(c)) |
|||
{ |
|||
b.Append(c); |
|||
reader.Read(); |
|||
readSign = c == '+' || c == '-'; |
|||
readPoint = c == '.'; |
|||
|
|||
if (c == 'E') |
|||
{ |
|||
readSign = false; |
|||
readExponent = c == 'E'; |
|||
} |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
|
|||
return double.Parse(b.ToString()); |
|||
} |
|||
|
|||
private static Point ReadPoint(StringReader reader) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
double x = ReadDouble(reader); |
|||
ReadSeparator(reader); |
|||
double y = ReadDouble(reader); |
|||
return new Point(x, y); |
|||
} |
|||
|
|||
private static Point ReadRelativePoint(StringReader reader, Point lastPoint) |
|||
{ |
|||
ReadWhitespace(reader); |
|||
double x = ReadDouble(reader); |
|||
ReadSeparator(reader); |
|||
double y = ReadDouble(reader); |
|||
return new Point(lastPoint.X + x, lastPoint.Y + y); |
|||
} |
|||
|
|||
private static void ReadSeparator(StringReader reader) |
|||
{ |
|||
int i; |
|||
bool readComma = false; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = (char)i; |
|||
|
|||
if (char.IsWhiteSpace(c)) |
|||
{ |
|||
reader.Read(); |
|||
} |
|||
else if (c == ',') |
|||
{ |
|||
if (readComma) |
|||
{ |
|||
throw new InvalidDataException("Unexpected ','."); |
|||
} |
|||
|
|||
readComma = true; |
|||
reader.Read(); |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
|
|||
private static void ReadWhitespace(StringReader reader) |
|||
{ |
|||
int i; |
|||
|
|||
while ((i = reader.Peek()) != -1) |
|||
{ |
|||
char c = (char)i; |
|||
|
|||
if (char.IsWhiteSpace(c)) |
|||
{ |
|||
reader.Read(); |
|||
} |
|||
else |
|||
{ |
|||
break; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,16 @@ |
|||
// -----------------------------------------------------------------------
|
|||
// <copyright file="Stretch.cs" company="Steven Kirk">
|
|||
// Copyright 2013 MIT Licence. See licence.md for more information.
|
|||
// </copyright>
|
|||
// -----------------------------------------------------------------------
|
|||
|
|||
namespace Perspex.Media |
|||
{ |
|||
public enum Stretch |
|||
{ |
|||
None, |
|||
Fill, |
|||
Uniform, |
|||
UniformToFill, |
|||
} |
|||
} |
|||
Loading…
Reference in new issue