/// <summary>Calculates and returns the next element which is either gap or dash.</summary>
 /// <returns>The next dash array's element.</returns>
 private LineDashPattern.DashArrayElem Next()
 {
     LineDashPattern.DashArrayElem ret = currentElem;
     if (dashArray.Size() > 0)
     {
         currentIndex = (currentIndex + 1) % dashArray.Size();
         currentElem  = new LineDashPattern.DashArrayElem(this, dashArray.GetAsNumber(currentIndex).FloatValue(), IsEven
                                                              (++elemOrdinalNumber));
     }
     return(ret);
 }
        /// <summary>Apply a LineDashPattern along a Path</summary>
        /// <param name="path">input path</param>
        /// <param name="lineDashPattern">input LineDashPattern</param>
        /// <returns>a dashed Path</returns>
        public static Path ApplyDashPattern(Path path, LineDashPattern lineDashPattern)
        {
            ICollection <int> modifiedSubpaths = new HashSet <int>(path.ReplaceCloseWithLine());
            Path dashedPath     = new Path();
            int  currentSubpath = 0;

            foreach (Subpath subpath in path.GetSubpaths())
            {
                IList <Point> subpathApprox = subpath.GetPiecewiseLinearApproximation();
                if (subpathApprox.Count > 1)
                {
                    dashedPath.MoveTo((float)subpathApprox[0].GetX(), (float)subpathApprox[0].GetY());
                    float remainingDist  = 0;
                    bool  remainingIsGap = false;
                    for (int i = 1; i < subpathApprox.Count; ++i)
                    {
                        Point nextPoint = null;
                        if (remainingDist != 0)
                        {
                            nextPoint     = GetNextPoint(subpathApprox[i - 1], subpathApprox[i], remainingDist);
                            remainingDist = ApplyDash(dashedPath, subpathApprox[i - 1], subpathApprox[i], nextPoint, remainingIsGap);
                        }
                        while (JavaUtil.FloatCompare(remainingDist, 0) == 0 && !dashedPath.GetCurrentPoint().Equals(subpathApprox[
                                                                                                                        i]))
                        {
                            LineDashPattern.DashArrayElem currentElem = lineDashPattern.Next();
                            nextPoint = GetNextPoint(nextPoint != null ? nextPoint : subpathApprox[i - 1], subpathApprox[i], currentElem
                                                     .GetVal());
                            remainingDist = ApplyDash(dashedPath, subpathApprox[i - 1], subpathApprox[i], nextPoint, currentElem.IsGap
                                                          ());
                            remainingIsGap = currentElem.IsGap();
                        }
                    }
                    // If true, then the line closing the subpath was explicitly added (see Path.ReplaceCloseWithLine).
                    // This causes a loss of a visual effect of line join style parameter, so in this clause
                    // we simply add overlapping dash (or gap, no matter), which continues the last dash and equals to
                    // the first dash (or gap) of the path.
                    if (modifiedSubpaths.Contains(currentSubpath))
                    {
                        lineDashPattern.Reset();
                        LineDashPattern.DashArrayElem currentElem = lineDashPattern.Next();
                        Point nextPoint = GetNextPoint(subpathApprox[0], subpathApprox[1], currentElem.GetVal());
                        ApplyDash(dashedPath, subpathApprox[0], subpathApprox[1], nextPoint, currentElem.IsGap());
                    }
                }
                // According to PDF spec. line dash pattern should be restarted for each new subpath.
                lineDashPattern.Reset();
                ++currentSubpath;
            }
            return(dashedPath);
        }
 private void InitFirst(float phase)
 {
     if (dashArray.Size() > 0)
     {
         while (phase > 0)
         {
             phase       -= dashArray.GetAsNumber(currentIndex).FloatValue();
             currentIndex = (currentIndex + 1) % dashArray.Size();
             elemOrdinalNumber++;
         }
         if (phase < 0)
         {
             --elemOrdinalNumber;
             --currentIndex;
             currentElem = new LineDashPattern.DashArrayElem(this, -phase, IsEven(elemOrdinalNumber));
         }
         else
         {
             currentElem = new LineDashPattern.DashArrayElem(this, dashArray.GetAsNumber(currentIndex).FloatValue(), IsEven
                                                                 (elemOrdinalNumber));
         }
     }
 }