internal void DeInitializeWorkingPath() { _isInitialized = false; _geometry = null; _context = null; _path = null; }
internal void InitializeWorkingPath(XPoint start) { _geometry = XPathGeometry.Create( ImmutableArray.Create <XPathFigure>(), _editor.Project.Options.DefaultFillRule); _context = new XPathGeometryContext(_geometry); _context.BeginFigure( start, _editor.Project.Options.DefaultIsFilled, _editor.Project.Options.DefaultIsClosed); var style = _editor.Project.CurrentStyleLibrary.Selected; _path = XPath.Create( "Path", _editor.Project.Options.CloneStyle ? style.Clone() : style, _geometry, _editor.Project.Options.DefaultIsStroked, _editor.Project.Options.DefaultIsFilled); _editor.Project.CurrentContainer.WorkingLayer.Shapes = _editor.Project.CurrentContainer.WorkingLayer.Shapes.Add(_path); _previousPathTool = _editor.CurrentPathTool; _isInitialized = true; }
public void ToString_Should_Return_Path_Markup_Empty_Nonzero() { var target = new XPathGeometry(); var actual = target.ToString(); Assert.Equal("F1", actual); }
public void ToString_Should_Return_Empty() { var geometry = new XPathGeometry(); var target = ImmutableArray.Create <XPathFigure>(); var actual = geometry.ToString(target); Assert.Equal(string.Empty, actual); }
public void ToString_Should_Return_Path_Markup_Empty_EvenOdd() { var target = new XPathGeometry() { FillRule = XFillRule.EvenOdd }; var actual = target.ToString(); Assert.Equal("", actual); }
/// <summary> /// Creates a new <see cref="XPath"/> instance. /// </summary> /// <param name="name">The shape name.</param> /// <param name="style">The shape style.</param> /// <param name="geometry">The path geometry.</param> /// <param name="isStroked">The flag indicating whether shape is stroked.</param> /// <param name="isFilled">The flag indicating whether shape is filled.</param> /// <returns>The new instance of the <see cref="XPath"/> class.</returns> public static XPath Create(string name, ShapeStyle style, XPathGeometry geometry, bool isStroked = true, bool isFilled = true) { return(new XPath() { Name = name, Style = style, IsStroked = isStroked, IsFilled = isFilled, Geometry = geometry }); }
/// <inheritdoc/> XPath IShapeFactory.Path(XPathGeometry geometry, bool isStroked, bool isFilled) { var style = _editor.Project.CurrentStyleLibrary.Selected; var path = XPath.Create( "", _editor.Project.Options.CloneStyle ? style.Clone() : style, geometry, isStroked, isFilled); _editor.Project.AddShape(_editor.Project.CurrentContainer.CurrentLayer, path); return(path); }
private void Remove(XPathGeometry geometry) { if (geometry == null) { return; } geometry.PropertyChanged -= ObserveShape; if (geometry.Figures != null) { Remove(geometry.Figures); } }
private void Add(XPathGeometry geometry) { if (geometry == null) { return; } geometry.PropertyChanged += ObserveShape; if (geometry.Figures != null) { Add(geometry.Figures); } }
public void BeginFigure_Adds_New_Figure() { var geometry = new XPathGeometry(); var target = new XPathGeometryContext(geometry); Assert.Equal(0, geometry.Figures.Length); target.BeginFigure(new XPoint()); Assert.Equal(1, geometry.Figures.Length); Assert.True(geometry.Figures[0].IsFilled); Assert.True(geometry.Figures[0].IsClosed); target.SetClosedState(false); Assert.False(geometry.Figures[0].IsClosed); }
public void PolyQuadraticBezierTo_Adds_New_XPolyQuadraticBezierSegment() { var geometry = new XPathGeometry(); var target = new XPathGeometryContext(geometry); target.BeginFigure(new XPoint()); Assert.Equal(0, geometry.Figures[0].Segments.Length); target.PolyQuadraticBezierTo(ImmutableArray.Create <XPoint>(new XPoint(), new XPoint(), new XPoint())); Assert.Equal(1, geometry.Figures[0].Segments.Length); var segment = geometry.Figures[0].Segments[0]; Assert.IsType <XPolyQuadraticBezierSegment>(segment); Assert.True(segment.IsStroked); Assert.True(segment.IsSmoothJoin); }
public void CubicBezierTo_Adds_New_XCubicBezierSegment() { var geometry = new XPathGeometry(); var target = new XPathGeometryContext(geometry); target.BeginFigure(new XPoint()); Assert.Equal(0, geometry.Figures[0].Segments.Length); target.CubicBezierTo(new XPoint(), new XPoint(), new XPoint()); Assert.Equal(1, geometry.Figures[0].Segments.Length); var segment = geometry.Figures[0].Segments[0]; Assert.IsType <XCubicBezierSegment>(segment); Assert.True(segment.IsStroked); Assert.True(segment.IsSmoothJoin); }
/// <summary> /// Parse a mini-language string representation of the <see cref="XPathGeometry"/>. /// </summary> /// <remarks> /// The path geometry syntax may start with a "wsp*Fwsp*(0|1)" which indicate the winding mode (F0 is EvenOdd while F1 is NonZero). /// </remarks> /// <param name="source">The string with geometry data.</param> /// <returns>The new instance of the <see cref="XPathGeometry"/> class.</returns> public static XPathGeometry Parse(string source) { var fillRule = XFillRule.EvenOdd; var geometry = XPathGeometry.Create(ImmutableArray.Create <XPathFigure>(), fillRule); if (source != null) { int curIndex = 0; while ((curIndex < source.Length) && Char.IsWhiteSpace(source, curIndex)) { curIndex++; } if (curIndex < source.Length) { if (source[curIndex] == 'F') { curIndex++; while ((curIndex < source.Length) && Char.IsWhiteSpace(source, curIndex)) { curIndex++; } if ((curIndex == source.Length) || ((source[curIndex] != '0') && (source[curIndex] != '1'))) { throw new FormatException("Illegal token."); } fillRule = source[curIndex] == '0' ? XFillRule.EvenOdd : XFillRule.Nonzero; curIndex++; } } var parser = new SvgToXPathGeometryParser(); var context = new XPathGeometryContext(geometry); parser.Parse(context, source, curIndex); } geometry.FillRule = fillRule; return(geometry); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static StreamGeometry ToStreamGeometry(this XPathGeometry xpg) { var sg = new StreamGeometry(); var sgc = sg.Open(); var previous = default(XPoint); foreach (var xpf in xpg.Figures) { sgc.BeginFigure( new Point(xpf.StartPoint.X, xpf.StartPoint.Y), xpf.IsFilled); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; sgc.ArcTo( new Point(arcSegment.Point.X, arcSegment.Point.Y), new Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == XSweepDirection.Clockwise ? SweepDirection.Clockwise : SweepDirection.CounterClockwise); previous = arcSegment.Point; } else if (segment is XBezierSegment) { var bezierSegment = segment as XBezierSegment; sgc.BezierTo( new Point(bezierSegment.Point1.X, bezierSegment.Point1.Y), new Point(bezierSegment.Point2.X, bezierSegment.Point2.Y), new Point(bezierSegment.Point3.X, bezierSegment.Point3.Y)); previous = bezierSegment.Point3; } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; sgc.LineTo( new Point(lineSegment.Point.X, lineSegment.Point.Y)); previous = lineSegment.Point; } else if (segment is XPolyBezierSegment) { var polyBezierSegment = segment as XPolyBezierSegment; if (polyBezierSegment.Points.Count >= 3) { sgc.BezierTo( new Point( polyBezierSegment.Points[0].X, polyBezierSegment.Points[0].Y), new Point( polyBezierSegment.Points[1].X, polyBezierSegment.Points[1].Y), new Point( polyBezierSegment.Points[2].X, polyBezierSegment.Points[2].Y)); previous = polyBezierSegment.Points[2]; } if (polyBezierSegment.Points.Count > 3 && polyBezierSegment.Points.Count % 3 == 0) { for (int i = 3; i < polyBezierSegment.Points.Count; i += 3) { sgc.BezierTo( new Point( polyBezierSegment.Points[i].X, polyBezierSegment.Points[i].Y), new Point( polyBezierSegment.Points[i + 1].X, polyBezierSegment.Points[i + 1].Y), new Point( polyBezierSegment.Points[i + 2].X, polyBezierSegment.Points[i + 2].Y)); previous = polyBezierSegment.Points[i + 2]; } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Count >= 1) { sgc.LineTo( new Point( polyLineSegment.Points[0].X, polyLineSegment.Points[0].Y)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Count > 1) { for (int i = 1; i < polyLineSegment.Points.Count; i++) { sgc.LineTo( new Point( polyLineSegment.Points[i].X, polyLineSegment.Points[i].Y)); previous = polyLineSegment.Points[i]; } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Count >= 2) { var p1 = previous; var p2 = polyQuadraticSegment.Points[0]; var p3 = polyQuadraticSegment.Points[1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; sgc.BezierTo( new Point(x2, y2), new Point(x3, y3), new Point(x4, y4)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Count > 2 && polyQuadraticSegment.Points.Count % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3) { var p1 = polyQuadraticSegment.Points[i - 1]; var p2 = polyQuadraticSegment.Points[i]; var p3 = polyQuadraticSegment.Points[i + 1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; sgc.BezierTo( new Point(x2, y2), new Point(x3, y3), new Point(x4, y4)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is XQuadraticBezierSegment) { var qbezierSegment = segment as XQuadraticBezierSegment; var p1 = previous; var p2 = qbezierSegment.Point1; var p3 = qbezierSegment.Point2; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; sgc.BezierTo( new Point(x2, y2), new Point(x3, y3), new Point(x4, y4)); previous = qbezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } sgc.EndFigure(xpf.IsClosed); } // TODO: Perspex does not need to dispose StreamGeometryContext? //sgc.Close(); sgc.Dispose(); // TODO: Perspex has not yet implemented FillRule. //sg.FillRule = xpg.FillRule == XFillRule.Nonzero ? FillRule.Nonzero : FillRule.EvenOdd; return(sg); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static Geometry ToGeometry(this XPathGeometry xpg) { return(ToStreamGeometry(xpg)); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static Geometry ToGeometry(this XPathGeometry xpg, double dx, double dy) { return(ToStreamGeometry(xpg, dx, dy)); }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <returns></returns> public static XPathGeometry ToXPathGeometry(this PathGeometry pg) { var xpg = XPathGeometry.Create( new List <XPathFigure>(), pg.FillRule == FillRule.EvenOdd ? XFillRule.EvenOdd : XFillRule.Nonzero); foreach (var pf in pg.Figures) { xpg.BeginFigure( XPoint.Create(pf.StartPoint.X, pf.StartPoint.Y), pf.IsFilled, pf.IsClosed); foreach (var segment in pf.Segments) { if (segment is ArcSegment) { var arcSegment = segment as ArcSegment; xpg.ArcTo( XPoint.Create(arcSegment.Point.X, arcSegment.Point.Y), XPathSize.Create(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is BezierSegment) { var bezierSegment = segment as BezierSegment; xpg.BezierTo( XPoint.Create(bezierSegment.Point1.X, bezierSegment.Point1.Y), XPoint.Create(bezierSegment.Point2.X, bezierSegment.Point2.Y), XPoint.Create(bezierSegment.Point3.X, bezierSegment.Point3.Y), bezierSegment.IsStroked, bezierSegment.IsSmoothJoin); } else if (segment is LineSegment) { var lineSegment = segment as LineSegment; xpg.LineTo( XPoint.Create(lineSegment.Point.X, lineSegment.Point.Y), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is PolyBezierSegment) { var polyBezierSegment = segment as PolyBezierSegment; xpg.PolyBezierTo( ToXPoints(polyBezierSegment.Points), polyBezierSegment.IsStroked, polyBezierSegment.IsSmoothJoin); } else if (segment is PolyLineSegment) { var polyLineSegment = segment as PolyLineSegment; xpg.PolyLineTo( ToXPoints(polyLineSegment.Points), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is PolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; xpg.PolyQuadraticBezierTo( ToXPoints(polyQuadraticSegment.Points), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is QuadraticBezierSegment) { var qbezierSegment = segment as QuadraticBezierSegment; xpg.QuadraticBezierTo( XPoint.Create(qbezierSegment.Point1.X, qbezierSegment.Point1.Y), XPoint.Create(qbezierSegment.Point2.X, qbezierSegment.Point2.Y), qbezierSegment.IsStroked, qbezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } return(xpg); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static SKPath ToSKPath(this XPathGeometry xpg, double dx, double dy, Func <double, float> scale) { var path = new SKPath(); path.FillType = xpg.FillRule == XFillRule.EvenOdd ? SKPathFillType.EvenOdd : SKPathFillType.Winding; foreach (var xpf in xpg.Figures) { var previous = default(XPoint); // Begin new figure. path.MoveTo( scale(xpf.StartPoint.X + dx), scale(xpf.StartPoint.Y + dy)); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; path.ArcTo( scale(arcSegment.Size.Width), scale(arcSegment.Size.Height), (float)arcSegment.RotationAngle, arcSegment.IsLargeArc ? SKPathArcSize.Large : SKPathArcSize.Small, arcSegment.SweepDirection == XSweepDirection.Clockwise ? SKPathDirection.Clockwise : SKPathDirection.CounterClockwise, scale(arcSegment.Point.X + dx), scale(arcSegment.Point.Y + dy)); previous = arcSegment.Point; } else if (segment is XCubicBezierSegment) { var cubicBezierSegment = segment as XCubicBezierSegment; path.CubicTo( scale(cubicBezierSegment.Point1.X + dx), scale(cubicBezierSegment.Point1.Y + dy), scale(cubicBezierSegment.Point2.X + dx), scale(cubicBezierSegment.Point2.Y + dy), scale(cubicBezierSegment.Point3.X + dx), scale(cubicBezierSegment.Point3.Y + dy)); previous = cubicBezierSegment.Point3; } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; path.LineTo( scale(lineSegment.Point.X + dx), scale(lineSegment.Point.Y + dy)); previous = lineSegment.Point; } else if (segment is XPolyCubicBezierSegment) { var polyCubicBezierSegment = segment as XPolyCubicBezierSegment; if (polyCubicBezierSegment.Points.Length >= 3) { path.CubicTo( scale(polyCubicBezierSegment.Points[0].X + dx), scale(polyCubicBezierSegment.Points[0].Y + dy), scale(polyCubicBezierSegment.Points[1].X + dx), scale(polyCubicBezierSegment.Points[1].Y + dy), scale(polyCubicBezierSegment.Points[2].X + dx), scale(polyCubicBezierSegment.Points[2].Y + dy)); previous = polyCubicBezierSegment.Points[2]; } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { path.CubicTo( scale(polyCubicBezierSegment.Points[i].X + dx), scale(polyCubicBezierSegment.Points[i].Y + dy), scale(polyCubicBezierSegment.Points[i + 1].X + dx), scale(polyCubicBezierSegment.Points[i + 1].Y + dy), scale(polyCubicBezierSegment.Points[i + 2].X + dx), scale(polyCubicBezierSegment.Points[i + 2].Y + dy)); previous = polyCubicBezierSegment.Points[i + 2]; } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Length >= 1) { path.LineTo( scale(polyLineSegment.Points[0].X + dx), scale(polyLineSegment.Points[0].Y + dy)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { path.LineTo( scale(polyLineSegment.Points[i].X + dx), scale(polyLineSegment.Points[i].Y + dy)); previous = polyLineSegment.Points[i]; } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Length >= 2) { path.QuadTo( scale(polyQuadraticSegment.Points[0].X + dx), scale(polyQuadraticSegment.Points[0].Y + dy), scale(polyQuadraticSegment.Points[1].X + dx), scale(polyQuadraticSegment.Points[1].Y + dy)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { path.QuadTo( scale(polyQuadraticSegment.Points[i].X + dx), scale(polyQuadraticSegment.Points[i].Y + dy), scale(polyQuadraticSegment.Points[i + 1].X + dx), scale(polyQuadraticSegment.Points[i + 1].Y + dy)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is XQuadraticBezierSegment) { var quadraticBezierSegment = segment as XQuadraticBezierSegment; path.QuadTo( scale(quadraticBezierSegment.Point1.X + dx), scale(quadraticBezierSegment.Point1.Y + dy), scale(quadraticBezierSegment.Point2.X + dx), scale(quadraticBezierSegment.Point2.Y + dy)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (xpf.IsClosed) { path.Close(); } } return(path); }
/// <inheritdoc/> XPathGeometry IShapeFactory.Geometry(XFillRule fillRule) { return(XPathGeometry.Create( ImmutableArray.Create <XPathFigure>(), fillRule)); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static string ToSource(this XPathGeometry xpg) { var sg = ToStreamGeometry(xpg); return(sg.ToString()); }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <param name="scale"></param> /// <returns></returns> public static GraphicsPath ToGraphicsPath(this XPathGeometry pg, double dx, double dy, Func <double, float> scale) { var gp = new GraphicsPath(); gp.FillMode = pg.FillRule == Test2d.XFillRule.EvenOdd ? FillMode.Alternate : FillMode.Winding; foreach (var pf in pg.Figures) { var startPoint = pf.StartPoint; foreach (var segment in pf.Segments) { if (segment is Test2d.XArcSegment) { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); //var arcSegment = segment as Test2d.XArcSegment; // TODO: Convert WPF/SVG elliptical arc segment format to GDI+ bezier curves. //startPoint = arcSegment.Point; } else if (segment is Test2d.XBezierSegment) { var bezierSegment = segment as Test2d.XBezierSegment; gp.AddBezier( new PointF( scale(startPoint.X), scale(startPoint.Y)), new PointF( scale(bezierSegment.Point1.X), scale(bezierSegment.Point1.Y)), new PointF( scale(bezierSegment.Point2.X), scale(bezierSegment.Point2.Y)), new PointF( scale(bezierSegment.Point3.X), scale(bezierSegment.Point3.Y))); startPoint = bezierSegment.Point3; } else if (segment is Test2d.XLineSegment) { var lineSegment = segment as Test2d.XLineSegment; gp.AddLine( scale(startPoint.X), scale(startPoint.Y), scale(lineSegment.Point.X), scale(lineSegment.Point.Y)); startPoint = lineSegment.Point; } else if (segment is Test2d.XPolyBezierSegment) { var polyBezierSegment = segment as Test2d.XPolyBezierSegment; if (polyBezierSegment.Points.Count >= 3) { gp.AddBezier( new PointF( scale(startPoint.X), scale(startPoint.Y)), new PointF( scale(polyBezierSegment.Points[0].X), scale(polyBezierSegment.Points[0].Y)), new PointF( scale(polyBezierSegment.Points[1].X), scale(polyBezierSegment.Points[1].Y)), new PointF( scale(polyBezierSegment.Points[2].X), scale(polyBezierSegment.Points[2].Y))); } if (polyBezierSegment.Points.Count > 3 && polyBezierSegment.Points.Count % 3 == 0) { for (int i = 3; i < polyBezierSegment.Points.Count; i += 3) { gp.AddBezier( new PointF( scale(polyBezierSegment.Points[i - 1].X), scale(polyBezierSegment.Points[i - 1].Y)), new PointF( scale(polyBezierSegment.Points[i].X), scale(polyBezierSegment.Points[i].Y)), new PointF( scale(polyBezierSegment.Points[i + 1].X), scale(polyBezierSegment.Points[i + 1].Y)), new PointF( scale(polyBezierSegment.Points[i + 2].X), scale(polyBezierSegment.Points[i + 2].Y))); } } startPoint = polyBezierSegment.Points.Last(); } else if (segment is Test2d.XPolyLineSegment) { var polyLineSegment = segment as Test2d.XPolyLineSegment; if (polyLineSegment.Points.Count >= 1) { gp.AddLine( scale(startPoint.X), scale(startPoint.Y), scale(polyLineSegment.Points[0].X), scale(polyLineSegment.Points[0].Y)); } if (polyLineSegment.Points.Count > 1) { for (int i = 1; i < polyLineSegment.Points.Count; i++) { gp.AddLine( scale(polyLineSegment.Points[i - 1].X), scale(polyLineSegment.Points[i - 1].Y), scale(polyLineSegment.Points[i].X), scale(polyLineSegment.Points[i].Y)); } } startPoint = polyLineSegment.Points.Last(); } else if (segment is Test2d.XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as Test2d.XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Count >= 2) { var p1 = startPoint; var p2 = polyQuadraticSegment.Points[0]; var p3 = polyQuadraticSegment.Points[1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( new PointF( scale(x1 + dx), scale(y1 + dy)), new PointF( scale(x2 + dx), scale(y2 + dy)), new PointF( scale(x3 + dx), scale(y3 + dy)), new PointF( scale(x4 + dx), scale(y4 + dy))); } if (polyQuadraticSegment.Points.Count > 2 && polyQuadraticSegment.Points.Count % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3) { var p1 = polyQuadraticSegment.Points[i - 1]; var p2 = polyQuadraticSegment.Points[i]; var p3 = polyQuadraticSegment.Points[i + 1]; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( new PointF( scale(x1 + dx), scale(y1 + dy)), new PointF( scale(x2 + dx), scale(y2 + dy)), new PointF( scale(x3 + dx), scale(y3 + dy)), new PointF( scale(x4 + dx), scale(y4 + dy))); } } startPoint = polyQuadraticSegment.Points.Last(); } else if (segment is Test2d.XQuadraticBezierSegment) { var qbezierSegment = segment as Test2d.XQuadraticBezierSegment; var p1 = startPoint; var p2 = qbezierSegment.Point1; var p3 = qbezierSegment.Point2; double x1 = p1.X; double y1 = p1.Y; double x2 = p1.X + (2.0 * (p2.X - p1.X)) / 3.0; double y2 = p1.Y + (2.0 * (p2.Y - p1.Y)) / 3.0; double x3 = x2 + (p3.X - p1.X) / 3.0; double y3 = y2 + (p3.Y - p1.Y) / 3.0; double x4 = p3.X; double y4 = p3.Y; gp.AddBezier( new PointF( scale(x1 + dx), scale(y1 + dy)), new PointF( scale(x2 + dx), scale(y2 + dy)), new PointF( scale(x3 + dx), scale(y3 + dy)), new PointF( scale(x4 + dx), scale(y4 + dy))); startPoint = qbezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } if (pf.IsClosed) { gp.CloseFigure(); } else { gp.StartFigure(); } } return(gp); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static PathGeometry ToPathGeometry(this XPathGeometry xpg) { var sg = ToStreamGeometry(xpg); return(PathGeometry.CreateFromGeometry(sg)); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static StreamGeometry ToStreamGeometry(this XPathGeometry xpg, double dx, double dy) { var sg = new StreamGeometry(); using (var sgc = sg.Open()) { var previous = default(XPoint); sgc.SetFillRule(xpg.FillRule == XFillRule.Nonzero ? FillRule.NonZero : FillRule.EvenOdd); foreach (var xpf in xpg.Figures) { sgc.BeginFigure(new Point(xpf.StartPoint.X + dx, xpf.StartPoint.Y + dy), xpf.IsFilled); previous = xpf.StartPoint; foreach (var segment in xpf.Segments) { if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; sgc.ArcTo( new Point(arcSegment.Point.X + dx, arcSegment.Point.Y + dy), new Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == XSweepDirection.Clockwise ? SweepDirection.Clockwise : SweepDirection.CounterClockwise); previous = arcSegment.Point; } else if (segment is XCubicBezierSegment) { var cubicBezierSegment = segment as XCubicBezierSegment; sgc.CubicBezierTo( new Point(cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy), new Point(cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy), new Point(cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy)); previous = cubicBezierSegment.Point3; } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; sgc.LineTo( new Point(lineSegment.Point.X + dx, lineSegment.Point.Y + dy)); previous = lineSegment.Point; } else if (segment is XPolyCubicBezierSegment) { var polyCubicBezierSegment = segment as XPolyCubicBezierSegment; if (polyCubicBezierSegment.Points.Length >= 3) { sgc.CubicBezierTo( new Point( polyCubicBezierSegment.Points[0].X + dx, polyCubicBezierSegment.Points[0].Y + dy), new Point( polyCubicBezierSegment.Points[1].X + dx, polyCubicBezierSegment.Points[1].Y + dy), new Point( polyCubicBezierSegment.Points[2].X + dx, polyCubicBezierSegment.Points[2].Y + dy)); previous = polyCubicBezierSegment.Points[2]; } if (polyCubicBezierSegment.Points.Length > 3 && polyCubicBezierSegment.Points.Length % 3 == 0) { for (int i = 3; i < polyCubicBezierSegment.Points.Length; i += 3) { sgc.CubicBezierTo( new Point( polyCubicBezierSegment.Points[i].X + dx, polyCubicBezierSegment.Points[i].Y + dy), new Point( polyCubicBezierSegment.Points[i + 1].X + dx, polyCubicBezierSegment.Points[i + 1].Y + dy), new Point( polyCubicBezierSegment.Points[i + 2].X + dx, polyCubicBezierSegment.Points[i + 2].Y + dy)); previous = polyCubicBezierSegment.Points[i + 2]; } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Length >= 1) { sgc.LineTo( new Point( polyLineSegment.Points[0].X + dx, polyLineSegment.Points[0].Y + dy)); previous = polyLineSegment.Points[0]; } if (polyLineSegment.Points.Length > 1) { for (int i = 1; i < polyLineSegment.Points.Length; i++) { sgc.LineTo( new Point( polyLineSegment.Points[i].X + dx, polyLineSegment.Points[i].Y + dy)); previous = polyLineSegment.Points[i]; } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Length >= 2) { sgc.QuadraticBezierTo( new Point( polyQuadraticSegment.Points[0].X + dx, polyQuadraticSegment.Points[0].Y + dy), new Point( polyQuadraticSegment.Points[1].X + dx, polyQuadraticSegment.Points[1].Y + dy)); previous = polyQuadraticSegment.Points[1]; } if (polyQuadraticSegment.Points.Length > 2 && polyQuadraticSegment.Points.Length % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Length; i += 3) { sgc.QuadraticBezierTo( new Point( polyQuadraticSegment.Points[i].X + dx, polyQuadraticSegment.Points[i].Y + dy), new Point( polyQuadraticSegment.Points[i + 1].X + dx, polyQuadraticSegment.Points[i + 1].Y + dy)); previous = polyQuadraticSegment.Points[i + 1]; } } } else if (segment is XQuadraticBezierSegment) { var quadraticBezierSegment = segment as XQuadraticBezierSegment; sgc.QuadraticBezierTo( new Point( quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy), new Point( quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy)); previous = quadraticBezierSegment.Point2; } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } sgc.EndFigure(xpf.IsClosed); } } return(sg); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static string ToSource(this XPathGeometry xpg) { return(ToStreamGeometry(xpg, 0.0, 0.0).ToString()); }
/// <summary> /// /// </summary> /// <param name="pg"></param> /// <param name="dx"></param> /// <param name="dy"></param> /// <returns></returns> public static XPathGeometry ToXPathGeometry(this PathGeometry pg, double dx, double dy) { var geometry = XPathGeometry.Create( ImmutableArray.Create <XPathFigure>(), pg.FillRule == FillRule.EvenOdd ? XFillRule.EvenOdd : XFillRule.Nonzero); var context = new XPathGeometryContext(geometry); foreach (var pf in pg.Figures) { context.BeginFigure( XPoint.Create(pf.StartPoint.X + dx, pf.StartPoint.Y + dy), pf.IsFilled, pf.IsClosed); foreach (var segment in pf.Segments) { if (segment is ArcSegment) { var arcSegment = segment as ArcSegment; context.ArcTo( XPoint.Create(arcSegment.Point.X + dx, arcSegment.Point.Y + dy), XPathSize.Create(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == SweepDirection.Clockwise ? XSweepDirection.Clockwise : XSweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is BezierSegment) { var cubicBezierSegment = segment as BezierSegment; context.CubicBezierTo( XPoint.Create(cubicBezierSegment.Point1.X + dx, cubicBezierSegment.Point1.Y + dy), XPoint.Create(cubicBezierSegment.Point2.X + dx, cubicBezierSegment.Point2.Y + dy), XPoint.Create(cubicBezierSegment.Point3.X + dx, cubicBezierSegment.Point3.Y + dy), cubicBezierSegment.IsStroked, cubicBezierSegment.IsSmoothJoin); } else if (segment is LineSegment) { var lineSegment = segment as LineSegment; context.LineTo( XPoint.Create(lineSegment.Point.X + dx, lineSegment.Point.Y + dy), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is PolyBezierSegment) { var polyCubicBezierSegment = segment as PolyBezierSegment; context.PolyCubicBezierTo( ToXPoints(polyCubicBezierSegment.Points, dx, dy), polyCubicBezierSegment.IsStroked, polyCubicBezierSegment.IsSmoothJoin); } else if (segment is PolyLineSegment) { var polyLineSegment = segment as PolyLineSegment; context.PolyLineTo( ToXPoints(polyLineSegment.Points, dx, dy), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is PolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as PolyQuadraticBezierSegment; context.PolyQuadraticBezierTo( ToXPoints(polyQuadraticSegment.Points, dx, dy), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is QuadraticBezierSegment) { var quadraticBezierSegment = segment as QuadraticBezierSegment; context.QuadraticBezierTo( XPoint.Create(quadraticBezierSegment.Point1.X + dx, quadraticBezierSegment.Point1.Y + dy), XPoint.Create(quadraticBezierSegment.Point2.X + dx, quadraticBezierSegment.Point2.Y + dy), quadraticBezierSegment.IsStroked, quadraticBezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } return(geometry); }
public void Figures_Not_Null() { var target = new XPathGeometry(); Assert.NotNull(target.Figures); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static string ToSource(this XPathGeometry xpg) { var sg = ToStreamGeometry(xpg); return(sg.ToString(System.Globalization.CultureInfo.InvariantCulture)); }
public void FillRule_Set_To_Nonzero_By_Default() { var target = new XPathGeometry(); Assert.Equal(XFillRule.Nonzero, target.FillRule); }
public static CanvasGeometry ToCanvasGeometry(this XPathGeometry pg, CanvasDrawingSession ds) { CanvasGeometry g; using (var builder = new CanvasPathBuilder(ds)) { if (pg.FillRule == XFillRule.EvenOdd) { builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Alternate); } else { builder.SetFilledRegionDetermination(CanvasFilledRegionDetermination.Winding); } foreach (var pf in pg.Figures) { builder.BeginFigure( (float)pf.StartPoint.X, (float)pf.StartPoint.Y, pf.IsFilled ? CanvasFigureFill.Default : CanvasFigureFill.DoesNotAffectFills); foreach (var segment in pf.Segments) { var options = CanvasFigureSegmentOptions.None; if (!segment.IsStroked) { options |= CanvasFigureSegmentOptions.ForceUnstroked; } if (segment.IsSmoothJoin) { options |= CanvasFigureSegmentOptions.ForceRoundLineJoin; } builder.SetSegmentOptions(options); if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; builder.AddArc( new N.Vector2( (float)arcSegment.Point.X, (float)arcSegment.Point.Y), (float)(arcSegment.Size.Width / 2.0), (float)(arcSegment.Size.Height / 2.0), (float)arcSegment.RotationAngle, arcSegment.SweepDirection == XSweepDirection.Clockwise ? CanvasSweepDirection.Clockwise : CanvasSweepDirection.CounterClockwise, arcSegment.IsLargeArc ? CanvasArcSize.Large : CanvasArcSize.Small); } else if (segment is XBezierSegment) { var bezierSegment = segment as XBezierSegment; builder.AddCubicBezier( new N.Vector2( (float)bezierSegment.Point1.X, (float)bezierSegment.Point1.Y), new N.Vector2( (float)bezierSegment.Point2.X, (float)bezierSegment.Point2.Y), new N.Vector2( (float)bezierSegment.Point3.X, (float)bezierSegment.Point3.Y)); } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; builder.AddLine( new N.Vector2( (float)lineSegment.Point.X, (float)lineSegment.Point.Y)); } else if (segment is XPolyBezierSegment) { var polyBezierSegment = segment as XPolyBezierSegment; if (polyBezierSegment.Points.Count >= 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[0].X, (float)polyBezierSegment.Points[0].Y), new N.Vector2( (float)polyBezierSegment.Points[1].X, (float)polyBezierSegment.Points[1].Y), new N.Vector2( (float)polyBezierSegment.Points[2].X, (float)polyBezierSegment.Points[2].Y)); } if (polyBezierSegment.Points.Count > 3 && polyBezierSegment.Points.Count % 3 == 0) { for (int i = 3; i < polyBezierSegment.Points.Count; i += 3) { builder.AddCubicBezier( new N.Vector2( (float)polyBezierSegment.Points[i].X, (float)polyBezierSegment.Points[i].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 1].X, (float)polyBezierSegment.Points[i + 1].Y), new N.Vector2( (float)polyBezierSegment.Points[i + 2].X, (float)polyBezierSegment.Points[i + 2].Y)); } } } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; if (polyLineSegment.Points.Count >= 1) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[0].X, (float)polyLineSegment.Points[0].Y)); } if (polyLineSegment.Points.Count > 1) { for (int i = 1; i < polyLineSegment.Points.Count; i++) { builder.AddLine( new N.Vector2( (float)polyLineSegment.Points[i].X, (float)polyLineSegment.Points[i].Y)); } } } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; if (polyQuadraticSegment.Points.Count >= 2) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[0].X, (float)polyQuadraticSegment.Points[0].Y), new N.Vector2( (float)polyQuadraticSegment.Points[1].X, (float)polyQuadraticSegment.Points[1].Y)); } if (polyQuadraticSegment.Points.Count > 2 && polyQuadraticSegment.Points.Count % 2 == 0) { for (int i = 3; i < polyQuadraticSegment.Points.Count; i += 3) { builder.AddQuadraticBezier( new N.Vector2( (float)polyQuadraticSegment.Points[i].X, (float)polyQuadraticSegment.Points[i].Y), new N.Vector2( (float)polyQuadraticSegment.Points[i + 1].X, (float)polyQuadraticSegment.Points[i + 1].Y)); } } } else if (segment is XQuadraticBezierSegment) { var qbezierSegment = segment as XQuadraticBezierSegment; builder.AddQuadraticBezier( new N.Vector2( (float)qbezierSegment.Point1.X, (float)qbezierSegment.Point1.Y), new N.Vector2( (float)qbezierSegment.Point2.X, (float)qbezierSegment.Point2.Y)); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } builder.EndFigure(pf.IsClosed ? CanvasFigureLoop.Closed : CanvasFigureLoop.Open); } g = CanvasGeometry.CreatePath(builder); } return(g); }
/// <summary> /// /// </summary> /// <param name="xpg"></param> /// <returns></returns> public static StreamGeometry ToStreamGeometry(this XPathGeometry xpg) { var sg = new StreamGeometry(); var sgc = sg.Open(); foreach (var xpf in xpg.Figures) { sgc.BeginFigure( new Point(xpf.StartPoint.X, xpf.StartPoint.Y), xpf.IsFilled, xpf.IsClosed); foreach (var segment in xpf.Segments) { if (segment is XArcSegment) { var arcSegment = segment as XArcSegment; sgc.ArcTo( new Point(arcSegment.Point.X, arcSegment.Point.Y), new Size(arcSegment.Size.Width, arcSegment.Size.Height), arcSegment.RotationAngle, arcSegment.IsLargeArc, arcSegment.SweepDirection == XSweepDirection.Clockwise ? SweepDirection.Clockwise : SweepDirection.Counterclockwise, arcSegment.IsStroked, arcSegment.IsSmoothJoin); } else if (segment is XBezierSegment) { var bezierSegment = segment as XBezierSegment; sgc.BezierTo( new Point(bezierSegment.Point1.X, bezierSegment.Point1.Y), new Point(bezierSegment.Point2.X, bezierSegment.Point2.Y), new Point(bezierSegment.Point3.X, bezierSegment.Point3.Y), bezierSegment.IsStroked, bezierSegment.IsSmoothJoin); } else if (segment is XLineSegment) { var lineSegment = segment as XLineSegment; sgc.LineTo( new Point(lineSegment.Point.X, lineSegment.Point.Y), lineSegment.IsStroked, lineSegment.IsSmoothJoin); } else if (segment is XPolyBezierSegment) { var polyBezierSegment = segment as XPolyBezierSegment; sgc.PolyBezierTo( ToPoints(polyBezierSegment.Points), polyBezierSegment.IsStroked, polyBezierSegment.IsSmoothJoin); } else if (segment is XPolyLineSegment) { var polyLineSegment = segment as XPolyLineSegment; sgc.PolyLineTo( ToPoints(polyLineSegment.Points), polyLineSegment.IsStroked, polyLineSegment.IsSmoothJoin); } else if (segment is XPolyQuadraticBezierSegment) { var polyQuadraticSegment = segment as XPolyQuadraticBezierSegment; sgc.PolyQuadraticBezierTo( ToPoints(polyQuadraticSegment.Points), polyQuadraticSegment.IsStroked, polyQuadraticSegment.IsSmoothJoin); } else if (segment is XQuadraticBezierSegment) { var qbezierSegment = segment as XQuadraticBezierSegment; sgc.QuadraticBezierTo( new Point(qbezierSegment.Point1.X, qbezierSegment.Point1.Y), new Point(qbezierSegment.Point2.X, qbezierSegment.Point2.Y), qbezierSegment.IsStroked, qbezierSegment.IsSmoothJoin); } else { throw new NotSupportedException("Not supported segment type: " + segment.GetType()); } } } sgc.Close(); sg.FillRule = xpg.FillRule == XFillRule.Nonzero ? FillRule.Nonzero : FillRule.EvenOdd; sg.Freeze(); return(sg); }