Пример #1
0
        public void RawIteratorReturnsCorrectPointsAndVerb()
        {
            using (var path = new SKPath())
            {
                path.MoveTo(20, 20);
                path.QuadTo(20, 50, 80, 50);
                path.QuadTo(20, 50, 20, 80);

                using (var iter = path.CreateRawIterator())
                {
                    var points = new SKPoint[4];

                    var verb = iter.Next(points);
                    Assert.Equal(SKPathVerb.Move, verb);
                    Assert.Equal(new[] { new SKPoint(20, 20), SKPoint.Empty, SKPoint.Empty, SKPoint.Empty }, points);

                    verb = iter.Next(points);
                    Assert.Equal(SKPathVerb.Quad, verb);
                    Assert.Equal(new[] { new SKPoint(20, 20), new SKPoint(20, 50), new SKPoint(80, 50), SKPoint.Empty }, points);

                    verb = iter.Next(points);
                    Assert.Equal(SKPathVerb.Quad, verb);
                    Assert.Equal(new[] { new SKPoint(80, 50), new SKPoint(20, 50), new SKPoint(20, 80), SKPoint.Empty }, points);

                    verb = iter.Next(points);
                    Assert.Equal(SKPathVerb.Done, verb);
                    // note: when the iteration is Done, it doesn't touch the points
                    Assert.Equal(new[] { new SKPoint(80, 50), new SKPoint(20, 50), new SKPoint(20, 80), SKPoint.Empty }, points);
                }
            }
        }
        private static List <SKPoint> CreateLinearPathPoints(SKPath path)
        {
            var ring = new List <SKPoint>();

            using (var iterator = path.CreateRawIterator())
            {
                var points = new SKPoint[4];

                // we must start with a move
                var verb = iterator.Next(points);
                if (verb == SKPathVerb.Move)
                {
                    ring.Add(points[0]);

                    // loop through all the lines
                    while ((verb = iterator.Next(points)) == SKPathVerb.Line)
                    {
                        ring.Add(points[1]);
                    }

                    // if we encountered a curve of some sort, then this is invalid
                    if (verb != SKPathVerb.Move && verb != SKPathVerb.Close && verb != SKPathVerb.Done)
                    {
                        ring.Clear();
                    }
                }
            }

            return(ring.Count > 0 ? ring : null);
        }
Пример #3
0
        public static List <(SKPoint Point, byte Type)> GetPathTypes(this SKPath skPath)
        {
            // System.Drawing.Drawing2D.GraphicsPath.PathTypes
            // System.Drawing.Drawing2D.PathPointType
            // byte -> PathPointType
            var pathTypes = new List <(SKPoint Point, byte Type)>();

            using (var iterator = skPath.CreateRawIterator())
            {
                var points   = new SKPoint[4];
                var pathVerb = SKPathVerb.Move;
                (SKPoint Point, byte Type)lastPoint = (default, 0);
Пример #4
0
        public static void Generate(SKPath skPath, StringBuilder sb, string indent = "", string id = "skPath")
        {
            sb.AppendLine($"{indent}var {id} = new {nameof(SKPath)}()");
            sb.AppendLine($"{indent}{{");
            sb.AppendLine($"{indent}    {nameof(SKPath.FillType)} = {(skPath.FillType == SKPathFillType.Winding ? $"{nameof(SKPathFillType)}.{nameof(SKPathFillType.Winding)}" : $"{nameof(SKPathFillType)}.{nameof(SKPathFillType.EvenOdd)}")}");
            sb.AppendLine($"{indent}}};");

            using (var rawIterator = skPath.CreateRawIterator())
            {
                var skPoints   = new SKPoint[4];
                var skPathVerb = SKPathVerb.Move;
                while ((skPathVerb = rawIterator.Next(skPoints)) != SKPathVerb.Done)
                {
                    switch (skPathVerb)
                    {
                    case SKPathVerb.Move:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.MoveTo)}({skPoints[0].X.WriteFloat()}, {skPoints[0].Y.WriteFloat()});");
                        break;

                    case SKPathVerb.Line:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.LineTo)}({skPoints[1].X.WriteFloat()}, {skPoints[1].Y.WriteFloat()});");
                        break;

                    case SKPathVerb.Cubic:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.CubicTo)}({skPoints[1].X.WriteFloat()}, {skPoints[1].Y.WriteFloat()}, {skPoints[2].X.WriteFloat()}, {skPoints[2].Y.WriteFloat()}, {skPoints[3].X.WriteFloat()}, {skPoints[3].Y.WriteFloat()});");
                        break;

                    case SKPathVerb.Quad:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.QuadTo)}({skPoints[1].X.WriteFloat()}, {skPoints[1].Y.WriteFloat()}, {skPoints[2].X.WriteFloat()}, {skPoints[2].Y.WriteFloat()});");
                        break;

                    case SKPathVerb.Conic:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.ConicTo)}({skPoints[1].X.WriteFloat()}, {skPoints[1].Y.WriteFloat()}, {skPoints[2].X.WriteFloat()}, {skPoints[2].Y.WriteFloat()}, {rawIterator.ConicWeight().WriteFloat()});");
                        break;

                    case SKPathVerb.Close:
                        sb.AppendLine($"{indent}{id}.{nameof(SKPath.Close)}();");
                        break;

                    case SKPathVerb.Done:
                    default:
                        break;
                    }
                }
            }
        }
Пример #5
0
        public static IPathGeometry ToPathGeometry(SKPath path, double dx, double dy, IFactory factory)
        {
            var geometry = factory.CreatePathGeometry(
                ImmutableArray.Create <IPathFigure>(),
                path.FillType == SKPathFillType.EvenOdd ? FillRule.EvenOdd : FillRule.Nonzero);

            var context = factory.CreateGeometryContext(geometry);

            using (var iterator = path.CreateRawIterator())
            {
                var points   = new SKPoint[4];
                var pathVerb = SKPathVerb.Move;

                while ((pathVerb = iterator.Next(points)) != SKPathVerb.Done)
                {
                    switch (pathVerb)
                    {
                    case SKPathVerb.Move:
                    {
                        context.BeginFigure(
                            factory.CreatePointShape(points[0].X + dx, points[0].Y + dy),
                            false,
                            false);
                    }
                    break;

                    case SKPathVerb.Line:
                    {
                        context.LineTo(
                            factory.CreatePointShape(points[1].X + dx, points[1].Y + dy));
                    }
                    break;

                    case SKPathVerb.Cubic:
                    {
                        context.CubicBezierTo(
                            factory.CreatePointShape(points[1].X + dx, points[1].Y + dy),
                            factory.CreatePointShape(points[2].X + dx, points[2].Y + dy),
                            factory.CreatePointShape(points[3].X + dx, points[3].Y + dy));
                    }
                    break;

                    case SKPathVerb.Quad:
                    {
                        context.QuadraticBezierTo(
                            factory.CreatePointShape(points[1].X + dx, points[1].Y + dy),
                            factory.CreatePointShape(points[2].X + dx, points[2].Y + dy));
                    }
                    break;

                    case SKPathVerb.Conic:
                    {
                        var quads = SKPath.ConvertConicToQuads(points[0], points[1], points[2], iterator.ConicWeight(), 1);
                        context.QuadraticBezierTo(
                            factory.CreatePointShape(quads[1].X + dx, quads[1].Y + dy),
                            factory.CreatePointShape(quads[2].X + dx, quads[2].Y + dy));
                        context.QuadraticBezierTo(
                            factory.CreatePointShape(quads[3].X + dx, quads[3].Y + dy),
                            factory.CreatePointShape(quads[4].X + dx, quads[4].Y + dy));
                    }
                    break;

                    case SKPathVerb.Close:
                    {
                        context.SetClosedState(true);
                    }
                    break;
                    }
                }
            }

            return(geometry);
        }
Пример #6
0
        public static SKPath CloneWithTransform(this SKPath pathIn, Func <SKPoint, SKPoint> transform)
        {
            SKPath pathOut = new();

            using (SKPath.RawIterator iterator = pathIn.CreateRawIterator())
            {
                SKPoint[]  points     = new SKPoint[4];
                SKPathVerb pathVerb   = SKPathVerb.Move;
                SKPoint    firstPoint = new();
                SKPoint    lastPoint  = new();

                while ((pathVerb = iterator.Next(points)) != SKPathVerb.Done)
                {
                    switch (pathVerb)
                    {
                    case SKPathVerb.Move:
                        pathOut.MoveTo(transform(points[0]));
                        firstPoint = lastPoint = points[0];
                        break;

                    case SKPathVerb.Line:
                        SKPoint[] linePoints = Interpolate(points[0], points[1]);

                        foreach (SKPoint pt in linePoints)
                        {
                            pathOut.LineTo(transform(pt));
                        }

                        lastPoint = points[1];
                        break;

                    case SKPathVerb.Cubic:
                        SKPoint[] cubicPoints = FlattenCubic(points[0], points[1], points[2], points[3]);

                        foreach (SKPoint pt in cubicPoints)
                        {
                            pathOut.LineTo(transform(pt));
                        }

                        lastPoint = points[3];
                        break;

                    case SKPathVerb.Quad:
                        SKPoint[] quadPoints = FlattenQuadratic(points[0], points[1], points[2]);

                        foreach (SKPoint pt in quadPoints)
                        {
                            pathOut.LineTo(transform(pt));
                        }

                        lastPoint = points[2];
                        break;

                    case SKPathVerb.Conic:
                        SKPoint[] conicPoints = FlattenConic(points[0], points[1], points[2], iterator.ConicWeight());

                        foreach (SKPoint pt in conicPoints)
                        {
                            pathOut.LineTo(transform(pt));
                        }

                        lastPoint = points[2];
                        break;

                    case SKPathVerb.Close:
                        SKPoint[] closePoints = Interpolate(lastPoint, firstPoint);

                        foreach (SKPoint pt in closePoints)
                        {
                            pathOut.LineTo(transform(pt));
                        }

                        firstPoint = lastPoint = new SKPoint(0, 0);
                        pathOut.Close();
                        break;
                    }
                }
            }
            return(pathOut);
        }
Пример #7
0
    public static PathShapeViewModel ToPathGeometry(SKPath path, IViewModelFactory viewModelFactory)
    {
        var geometry = viewModelFactory.CreatePathShape(
            null,
            ImmutableArray.Create <PathFigureViewModel>(),
            path.FillType == SKPathFillType.EvenOdd ? FillRule.EvenOdd : FillRule.Nonzero);

        var context = viewModelFactory.CreateGeometryContext(geometry);

        using var iterator = path.CreateRawIterator();
        var points   = new SKPoint[4];
        var pathVerb = SKPathVerb.Move;

        while ((pathVerb = iterator.Next(points)) != SKPathVerb.Done)
        {
            switch (pathVerb)
            {
            case SKPathVerb.Move:
            {
                context.BeginFigure(
                    viewModelFactory.CreatePointShape(points[0].X, points[0].Y),
                    false);
            }
            break;

            case SKPathVerb.Line:
            {
                context.LineTo(
                    viewModelFactory.CreatePointShape(points[1].X, points[1].Y));
            }
            break;

            case SKPathVerb.Cubic:
            {
                context.CubicBezierTo(
                    viewModelFactory.CreatePointShape(points[1].X, points[1].Y),
                    viewModelFactory.CreatePointShape(points[2].X, points[2].Y),
                    viewModelFactory.CreatePointShape(points[3].X, points[3].Y));
            }
            break;

            case SKPathVerb.Quad:
            {
                context.QuadraticBezierTo(
                    viewModelFactory.CreatePointShape(points[1].X, points[1].Y),
                    viewModelFactory.CreatePointShape(points[2].X, points[2].Y));
            }
            break;

            case SKPathVerb.Conic:
            {
                var quads = SKPath.ConvertConicToQuads(points[0], points[1], points[2], iterator.ConicWeight(), 1);
                context.QuadraticBezierTo(
                    viewModelFactory.CreatePointShape(quads[1].X, quads[1].Y),
                    viewModelFactory.CreatePointShape(quads[2].X, quads[2].Y));
                context.QuadraticBezierTo(
                    viewModelFactory.CreatePointShape(quads[3].X, quads[3].Y),
                    viewModelFactory.CreatePointShape(quads[4].X, quads[4].Y));
            }
            break;

            case SKPathVerb.Close:
            {
                context.SetClosedState(true);
            }
            break;
            }
        }

        return(geometry);
    }
Пример #8
0
        internal static PathShape ToPathShape(IToolContext context, SKPath path, ShapeStyle style, IBaseShape pointTemplate)
        {
            var pathShape = new PathShape()
            {
                Points   = new ObservableCollection <IPointShape>(),
                Shapes   = new ObservableCollection <IBaseShape>(),
                FillType = ToPathFillType(path.FillType),
                Text     = new Text(),
                StyleId  = style.Title
            };

            var figureShape = default(FigureShape);

            using (var iterator = path.CreateRawIterator())
            {
                var points     = new SKPoint[4];
                var pathVerb   = SKPathVerb.Move;
                var firstPoint = new SKPoint();
                var lastPoint  = new SKPoint();

                while ((pathVerb = iterator.Next(points)) != SKPathVerb.Done)
                {
                    switch (pathVerb)
                    {
                    case SKPathVerb.Move:
                    {
                        figureShape = new FigureShape()
                        {
                            Points   = new ObservableCollection <IPointShape>(),
                            Shapes   = new ObservableCollection <IBaseShape>(),
                            IsFilled = true,
                            IsClosed = false
                        };
                        figureShape.Owner = pathShape;
                        pathShape.Shapes.Add(figureShape);
                        firstPoint = lastPoint = points[0];
                    }
                    break;

                    case SKPathVerb.Line:
                    {
                        var lastPointShape = pathShape.GetLastPoint();
                        if (lastPointShape == null)
                        {
                            lastPointShape = new PointShape(points[0].X, points[0].Y, pointTemplate);
                        }
                        var lineShape = new LineShape()
                        {
                            Points     = new ObservableCollection <IPointShape>(),
                            StartPoint = lastPointShape,
                            Point      = new PointShape(points[1].X, points[1].Y, pointTemplate),
                            Text       = new Text(),
                            StyleId    = style.Title
                        };
                        lineShape.Owner            = figureShape;
                        lineShape.StartPoint.Owner = lineShape;
                        lineShape.Point.Owner      = lineShape;
                        figureShape.Shapes.Add(lineShape);
                        lastPoint = points[1];
                    }
                    break;

                    case SKPathVerb.Cubic:
                    {
                        var lastPointShape = pathShape.GetLastPoint();
                        if (lastPointShape == null)
                        {
                            lastPointShape = new PointShape(points[0].X, points[0].Y, pointTemplate);
                        }
                        var cubicBezierShape = new CubicBezierShape()
                        {
                            Points     = new ObservableCollection <IPointShape>(),
                            StartPoint = lastPointShape,
                            Point1     = new PointShape(points[1].X, points[1].Y, pointTemplate),
                            Point2     = new PointShape(points[2].X, points[2].Y, pointTemplate),
                            Point3     = new PointShape(points[3].X, points[3].Y, pointTemplate),
                            Text       = new Text(),
                            StyleId    = style.Title
                        };
                        cubicBezierShape.Owner            = figureShape;
                        cubicBezierShape.StartPoint.Owner = cubicBezierShape;
                        cubicBezierShape.Point1.Owner     = cubicBezierShape;
                        cubicBezierShape.Point2.Owner     = cubicBezierShape;
                        cubicBezierShape.Point3.Owner     = cubicBezierShape;
                        figureShape.Shapes.Add(cubicBezierShape);
                        lastPoint = points[3];
                    }
                    break;

                    case SKPathVerb.Quad:
                    {
                        var lastPointShape = pathShape.GetLastPoint();
                        if (lastPointShape == null)
                        {
                            lastPointShape = new PointShape(points[0].X, points[0].Y, pointTemplate);
                        }
                        var quadraticBezierShape = new QuadraticBezierShape()
                        {
                            Points     = new ObservableCollection <IPointShape>(),
                            StartPoint = lastPointShape,
                            Point1     = new PointShape(points[1].X, points[1].Y, pointTemplate),
                            Point2     = new PointShape(points[2].X, points[2].Y, pointTemplate),
                            Text       = new Text(),
                            StyleId    = style.Title
                        };
                        quadraticBezierShape.Owner            = figureShape;
                        quadraticBezierShape.StartPoint.Owner = quadraticBezierShape;
                        quadraticBezierShape.Point1.Owner     = quadraticBezierShape;
                        quadraticBezierShape.Point2.Owner     = quadraticBezierShape;
                        figureShape.Shapes.Add(quadraticBezierShape);
                        lastPoint = points[2];
                    }
                    break;

                    case SKPathVerb.Conic:
                    {
                        var lastPointShape = pathShape.GetLastPoint();
                        if (lastPointShape == null)
                        {
                            lastPointShape = new PointShape(points[0].X, points[0].Y, pointTemplate);
                        }
                        var conicShape = new ConicShape()
                        {
                            Points     = new ObservableCollection <IPointShape>(),
                            StartPoint = lastPointShape,
                            Point1     = new PointShape(points[1].X, points[1].Y, pointTemplate),
                            Point2     = new PointShape(points[2].X, points[2].Y, pointTemplate),
                            Weight     = iterator.ConicWeight(),
                            Text       = new Text(),
                            StyleId    = style.Title
                        };
                        conicShape.Owner            = figureShape;
                        conicShape.StartPoint.Owner = conicShape;
                        conicShape.Point1.Owner     = conicShape;
                        conicShape.Point2.Owner     = conicShape;
                        figureShape.Shapes.Add(conicShape);
                        lastPoint = points[2];
                    }
                    break;

                    case SKPathVerb.Close:
                    {
#if USE_CLOSE_SHAPE
                        var line = new LineShape()
                        {
                            Points     = new ObservableCollection <IPointShape>(),
                            StartPoint = pathShape.GetLastPoint(),
                            Point      = pathShape.GetFirstPoint(),
                            Text       = new Text(),
                            StyleId    = style.Title
                        };
                        line.Owner            = figureShape;
                        line.StartPoint.Owner = line;
                        line.Point.Owner      = line;
                        figureShape.Shapes.Add(line);
#else
                        figureShape.IsClosed = true;
                        firstPoint           = lastPoint = new SKPoint(0, 0);
#endif
                    }
                    break;
                    }
                }
            }

            return(pathShape);
        }