/// <inheritdoc/> public IPathShape ToStrokePathShape(IBaseShape shape) { var path = PathGeometryConverter.ToSKPath(shape, 0.0, 0.0, (value) => (float)value); if (path == null) { return(null); } var factory = _serviceProvider.GetService <IFactory>(); var style = shape.Style != null ? (IShapeStyle)shape.Style?.Copy(null) : factory.CreateShapeStyle(ProjectEditorConfiguration.DefaulStyleName); using var paint = SkiaSharpRenderer.ToSKPaintPen(shape.Style, (value) => (float)value, 96.0, 96.0, true); var result = paint.GetFillPath(path, 1.0f); if (result != null) { if (result.IsEmpty) { result.Dispose(); return(null); } var geometry = PathGeometryConverter.ToPathGeometry(result, 0.0, 0.0, factory); var pathShape = factory.CreatePathShape( "Path", style, geometry, shape.IsStroked, shape.IsFilled); result.Dispose(); return(pathShape); } return(null); }
public static SKPath ToSKPath(this IEnumerable <IBaseShape> shapes, double dx, double dy, Func <double, float> scale) { var path = new SKPath { FillType = SKPathFillType.Winding }; var previous = default(IPointShape); foreach (var shape in shapes) { switch (shape) { case ILineShape lineShape: { if (previous == null || previous != lineShape.Start) { path.MoveTo( scale(lineShape.Start.X + dx), scale(lineShape.Start.Y + dy)); } path.LineTo( scale(lineShape.End.X + dx), scale(lineShape.End.Y + dy)); previous = lineShape.End; } break; case IRectangleShape rectangleShape: { path.AddRect( SkiaSharpRenderer.CreateRect(rectangleShape.TopLeft, rectangleShape.BottomRight, dx, dy, scale), SKPathDirection.Clockwise); } break; case IEllipseShape ellipseShape: { path.AddOval( SkiaSharpRenderer.CreateRect(ellipseShape.TopLeft, ellipseShape.BottomRight, dx, dy, scale), SKPathDirection.Clockwise); } break; case IArcShape arcShape: { var a = new GdiArc( Point2.FromXY(arcShape.Point1.X, arcShape.Point1.Y), Point2.FromXY(arcShape.Point2.X, arcShape.Point2.Y), Point2.FromXY(arcShape.Point3.X, arcShape.Point3.Y), Point2.FromXY(arcShape.Point4.X, arcShape.Point4.Y)); var rect = new SKRect( scale(a.X + dx), scale(a.Y + dy), scale(a.X + dx + a.Width), scale(a.Y + dy + a.Height)); path.AddArc(rect, (float)a.StartAngle, (float)a.SweepAngle); } break; case ICubicBezierShape cubicBezierShape: { if (previous == null || previous != cubicBezierShape.Point1) { path.MoveTo( scale(cubicBezierShape.Point1.X + dx), scale(cubicBezierShape.Point1.Y + dy)); } path.CubicTo( scale(cubicBezierShape.Point2.X + dx), scale(cubicBezierShape.Point2.Y + dy), scale(cubicBezierShape.Point3.X + dx), scale(cubicBezierShape.Point3.Y + dy), scale(cubicBezierShape.Point4.X + dx), scale(cubicBezierShape.Point4.Y + dy)); previous = cubicBezierShape.Point4; } break; case IQuadraticBezierShape quadraticBezierShape: { if (previous == null || previous != quadraticBezierShape.Point1) { path.MoveTo( scale(quadraticBezierShape.Point1.X + dx), scale(quadraticBezierShape.Point1.Y + dy)); } path.QuadTo( scale(quadraticBezierShape.Point2.X + dx), scale(quadraticBezierShape.Point2.Y + dy), scale(quadraticBezierShape.Point3.X + dx), scale(quadraticBezierShape.Point3.Y + dy)); previous = quadraticBezierShape.Point3; } break; case ITextShape textShape: { var resultPath = ToSKPath(textShape, dx, dy, scale); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; case IPathShape pathShape: { var resultPath = ToSKPath(pathShape, dx, dy, scale); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; case IGroupShape groupShape: { var resultPath = ToSKPath(groupShape.Shapes, dx, dy, scale); if (resultPath != null && !resultPath.IsEmpty) { path.AddPath(resultPath, SKPathAddMode.Append); } } break; } } return(path); }