/// <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; }
static SkiaSharp.SKPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation SkiaSharp.SKPath innerPath = path.InnerPath as SkiaSharp.SKPath; if (innerPath != null) { return(innerPath); } //-------- innerPath = new SkiaSharp.SKPath(); path.InnerPath = innerPath; List <float> points; List <PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: var oval = SkiaSharp.SKRect.Create(points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); innerPath.ArcTo(oval, points[p_index + 4], points[p_index + 5], true); p_index += 6; break; case PathCommand.Bezier: innerPath.MoveTo(points[p_index] , points[p_index + 1]); innerPath.CubicTo( points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: //? break; case PathCommand.Ellipse: innerPath.AddOval( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.Line: innerPath.MoveTo(points[p_index], points[p_index + 1]); innerPath.LineTo( points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRect( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.StartFigure: break; } } return(innerPath); }
static SkiaSharp.SKPath ResolveGraphicsPath(GraphicsPath path) { //convert from graphics path to internal presentation SkiaSharp.SKPath innerPath = path.InnerPath as SkiaSharp.SKPath; if (innerPath != null) { return innerPath; } //-------- innerPath = new SkiaSharp.SKPath(); path.InnerPath = innerPath; List<float> points; List<PathCommand> cmds; GraphicsPath.GetPathData(path, out points, out cmds); int j = cmds.Count; int p_index = 0; for (int i = 0; i < j; ++i) { PathCommand cmd = cmds[i]; switch (cmd) { default: throw new NotSupportedException(); case PathCommand.Arc: var oval = SkiaSharp.SKRect.Create(points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3]); innerPath.ArcTo(oval, points[p_index + 4], points[p_index + 5], true); p_index += 6; break; case PathCommand.Bezier: innerPath.MoveTo(points[p_index] , points[p_index + 1]); innerPath.CubicTo( points[p_index + 2], points[p_index + 3], points[p_index + 4], points[p_index + 5], points[p_index + 6], points[p_index + 7]); p_index += 8; break; case PathCommand.CloseFigure: //? break; case PathCommand.Ellipse: innerPath.AddOval( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.Line: innerPath.MoveTo(points[p_index], points[p_index + 1]); innerPath.LineTo( points[p_index + 2], points[p_index + 3]); p_index += 4; break; case PathCommand.Rect: innerPath.AddRect( SkiaSharp.SKRect.Create( points[p_index], points[p_index + 1], points[p_index + 2], points[p_index + 3] )); p_index += 4; break; case PathCommand.StartFigure: break; } } return innerPath; }