/// <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)); } } }