1

I have hit a road block using SkiaSharp recently. I have been porting older code from System.Drawing to SkiaSharp. The GraphicsPath class had a flatten method which converted the curves to a series of connected line segments.

https://msdn.microsoft.com/en-us/library/system.drawing.drawing2d.graphicspath.flatten(v=vs.110).aspx

I cannot seem to find an equivalent method for SkiaSharp. The SKPath Simplify method seems a bit hazy on what it actually does. In my testing it didn't appear to produce a flattened path.

https://developer.xamarin.com/api/member/SkiaSharp.SKPath.Simplify()/

Particleman
  • 661
  • 2
  • 7
  • 19

1 Answers1

2

At some point after I asked this question Xamarin added documentation to do this. It is located here

https://developer.xamarin.com/guides/xamarin-forms/advanced/skiasharp/curves/information/

static class PathExtensions
{
public static SKPath CloneWithTransform(this SKPath pathIn, Func<SKPoint, SKPoint> transform)
{
    SKPath pathOut = new SKPath();

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

        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;
}
...
}
Particleman
  • 661
  • 2
  • 7
  • 19