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(); }
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); }
internal CachedPathIterator(CachedPathIteratorFactory outerInstance) { _outerInstance = outerInstance; Next(); }