Example #1
0
 public void SetPath(Path path)
 {
     _originalPathIterator = new CachedPathIteratorFactory(new FullPathIterator(path));
     _path = path;
     _geometry?.Dispose();
     using (var factory = new Factory(FactoryType.SingleThreaded))
         _geometry = _path.GetGeometry(factory);
     Length = _geometry.ComputeLength();
 }
Example #2
0
        public float[] Approximate(float precision)
        {
            var pathIteratorFactory = new CachedPathIteratorFactory(new FullPathIterator(this));
            var pathIterator        = pathIteratorFactory.Iterator();

            float[] points        = new float[8];
            var     segmentPoints = new List <Vector2>();
            var     lengths       = new List <float>();
            float   errorSquared  = precision * precision;

            while (!pathIterator.Done)
            {
                var type = pathIterator.CurrentSegment(points);
                switch (type)
                {
                case PathIterator.ContourType.MoveTo:
                    AddMove(segmentPoints, lengths, points);
                    break;

                case PathIterator.ContourType.Close:
                    AddLine(segmentPoints, lengths, points);
                    break;

                case PathIterator.ContourType.Line:
                    AddLine(segmentPoints, lengths, points.Skip(2).ToArray());
                    break;

                case PathIterator.ContourType.Arc:
                    AddBezier(points, QuadraticBezierCalculation, segmentPoints, lengths, errorSquared, false);
                    break;

                case PathIterator.ContourType.Bezier:
                    AddBezier(points, CubicBezierCalculation, segmentPoints, lengths, errorSquared, true);
                    break;
                }

                pathIterator.Next();
            }

            if (!segmentPoints.Any())
            {
                int numVerbs = Contours.Count;
                if (numVerbs == 1)
                {
                    AddMove(segmentPoints, lengths, Contours[0].Points);
                }
                else
                {
                    // Invalid or empty path. Fall back to point(0,0)
                    AddMove(segmentPoints, lengths, new[] { 0.0f, 0.0f });
                }
            }

            float totalLength = lengths.Last();

            if (totalLength == 0)
            {
                // Lone Move instructions should still be able to animate at the same value.
                segmentPoints.Add(segmentPoints.Last());
                lengths.Add(1);
                totalLength = 1;
            }

            var numPoints = segmentPoints.Count;
            var approximationArraySize = numPoints * 3;

            var approximation = new float[approximationArraySize];

            int approximationIndex = 0;

            for (var i = 0; i < numPoints; i++)
            {
                var point = segmentPoints[i];
                approximation[approximationIndex++] = lengths[i] / totalLength;
                approximation[approximationIndex++] = point.X;
                approximation[approximationIndex++] = point.Y;
            }

            return(approximation);
        }
Example #3
0
 internal CachedPathIterator(CachedPathIteratorFactory outerInstance)
 {
     _outerInstance = outerInstance;
     Next();
 }