static void HandleNewSegmentJoining(PathDistanceForwardIterator pathIt, PathPatternIterator patternIt, JoiningInfo[] joiningInfo, float halfThickness, float[] segmentLengths)
        {
            joiningInfo[0] = joiningInfo[1];
            joiningInfo[1] = null;

            if (!patternIt.IsSolidAt(pathIt.LengthSoFar + segmentLengths[pathIt.CurrentSegment]))
            {
                return; // The joining center falls outside the pattern, so don't join... period
            }
            if (pathIt.Closed && pathIt.Segments.Count <= 2)
            {
                return; // Not enough segments to do proper closing
            }
            if (pathIt.Closed)
            {
                JoiningInfo closing;
                if ((pathIt.CurrentSegment == 0) || (pathIt.CurrentSegment == pathIt.Segments.Count - 2))
                {
                    closing = ForeseeJoining(
                        VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.Segments.Count - 2),
                        VectorUtils.PathSegmentAtIndex(pathIt.Segments, 0),
                        halfThickness, segmentLengths[pathIt.Segments.Count - 2]);

                    if (pathIt.CurrentSegment == 0)
                    {
                        joiningInfo[0] = closing;
                    }
                    else
                    {
                        joiningInfo[1] = closing;
                        return;
                    }
                }
                else if (pathIt.CurrentSegment > pathIt.Segments.Count - 2)
                {
                    return;
                }
            }
            else if (pathIt.CurrentSegment >= pathIt.Segments.Count - 2)
            {
                return;
            }

            joiningInfo[1] = ForeseeJoining(
                VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment),
                VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment + 1),
                halfThickness, segmentLengths[pathIt.CurrentSegment]);
        }
        static void TessellateRange(
            float distance, PathDistanceForwardIterator pathIt, PathPatternIterator patternIt, PathProperties pathProps,
            TessellationOptions tessellateOptions, JoiningInfo[] joiningInfo, float[] segmentLengths, float totalLength, int rangeIndex, List <Vector2> verts, List <UInt16> inds)
        {
            bool startOfLoop = pathIt.Closed && (pathIt.CurrentSegment == 0) && (pathIt.CurrentT == 0.0f);

            if (startOfLoop && (joiningInfo[0] != null))
            {
                GenerateJoining(joiningInfo[0], pathProps.Corners, pathProps.Stroke.HalfThickness, pathProps.Stroke.TippedCornerLimit, tessellateOptions, verts, inds);
            }
            else
            {
                var pathEnding = pathProps.Head;

                // If pattern at the end will overlap with beginning, use a chopped ending to allow merging
                if (pathIt.Closed && rangeIndex == 0 && patternIt.IsSolidAt(pathIt.CurrentT) && patternIt.IsSolidAt(totalLength))
                {
                    pathEnding = PathEnding.Chop;
                }

                GenerateTip(VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment), true, pathIt.CurrentT, pathEnding, pathProps.Stroke.HalfThickness, tessellateOptions, verts, inds);
            }

            float startingLength  = pathIt.LengthSoFar;
            float unitsRemaining  = Mathf.Min(tessellateOptions.StepDistance, distance);
            bool  endedEntirePath = false;

            for (;;)
            {
                var result = pathIt.AdvanceBy(unitsRemaining, out unitsRemaining);
                if (result == PathDistanceForwardIterator.Result.Ended)
                {
                    endedEntirePath = true;
                    break;
                }
                else if (result == PathDistanceForwardIterator.Result.NewSegment)
                {
                    if (joiningInfo[1] != null)
                    {
                        GenerateJoining(joiningInfo[1], pathProps.Corners, pathProps.Stroke.HalfThickness, pathProps.Stroke.TippedCornerLimit, tessellateOptions, verts, inds);
                    }
                    else
                    {
                        AddSegment(VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment), pathIt.CurrentT, pathProps.Stroke.HalfThickness, null, pathIt.SegmentLengthSoFar, verts, inds);
                    }
                    HandleNewSegmentJoining(pathIt, patternIt, joiningInfo, pathProps.Stroke.HalfThickness, segmentLengths);
                }

                if ((unitsRemaining <= Epsilon) &&
                    !TryGetMoreRemainingUnits(ref unitsRemaining, pathIt, startingLength, distance, tessellateOptions.StepDistance))
                {
                    break;
                }

                if (result == PathDistanceForwardIterator.Result.Stepped)
                {
                    AddSegment(VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment), pathIt.CurrentT, pathProps.Stroke.HalfThickness, joiningInfo, pathIt.SegmentLengthSoFar, verts, inds);
                }
            }

            // Ending
            if (endedEntirePath && pathIt.Closed)
            {
                // No joining needed, the start and end of the path should just connect
                inds.Add(0);
                inds.Add(1);
                inds.Add((UInt16)(verts.Count - 2));
                inds.Add((UInt16)(verts.Count - 1));
                inds.Add((UInt16)(verts.Count - 2));
                inds.Add(1);
            }
            else
            {
                AddSegment(VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment), pathIt.CurrentT, pathProps.Stroke.HalfThickness, joiningInfo, pathIt.SegmentLengthSoFar, verts, inds);
                GenerateTip(VectorUtils.PathSegmentAtIndex(pathIt.Segments, pathIt.CurrentSegment), false, pathIt.CurrentT, pathProps.Tail, pathProps.Stroke.HalfThickness, tessellateOptions, verts, inds);
            }
        }