Example #1
0
        /// <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);
        }