/// <summary>Approximates a given Path with a List of Point objects</summary> /// <param name="path">input path</param> private static IList <Point> GetPathApproximation(Path path) { IList <Point> approx = new ApproxPoints(); foreach (Subpath subpath in path.GetSubpaths()) { approx.AddAll(subpath.GetPiecewiseLinearApproximation()); } return(approx); }
private Path FilterStrokePath(Path sourcePath, Matrix ctm, float lineWidth, int lineCapStyle, int lineJoinStyle , float miterLimit, LineDashPattern lineDashPattern) { Path path = sourcePath; JoinType joinType = ClipperBridge.GetJoinType(lineJoinStyle); EndType endType = ClipperBridge.GetEndType(lineCapStyle); if (lineDashPattern != null) { if (!lineDashPattern.IsSolid()) { path = LineDashPattern.ApplyDashPattern(path, lineDashPattern); } } ClipperOffset offset = new ClipperOffset(miterLimit, PdfCleanUpTool.arcTolerance * PdfCleanUpTool.floatMultiplier ); IList <Subpath> degenerateSubpaths = ClipperBridge.AddPath(offset, path, joinType, endType); PolyTree resultTree = new PolyTree(); offset.Execute(ref resultTree, lineWidth * PdfCleanUpTool.floatMultiplier / 2); Path offsetedPath = ClipperBridge.ConvertToPath(resultTree); if (degenerateSubpaths.Count > 0) { if (endType == EndType.OPEN_ROUND) { IList <Subpath> circles = ConvertToCircles(degenerateSubpaths, lineWidth / 2); offsetedPath.AddSubpaths(circles); } else { if (endType == EndType.OPEN_SQUARE && lineDashPattern != null) { IList <Subpath> squares = ConvertToSquares(degenerateSubpaths, lineWidth, sourcePath); offsetedPath.AddSubpaths(squares); } } } return(FilterFillPath(offsetedPath, ctm, PdfCanvasConstants.FillingRule.NONZERO_WINDING)); }
/// <summary>Note: this method will close all unclosed subpaths of the passed path.</summary> /// <param name="fillingRule">If the subpath is contour, pass any value.</param> protected internal virtual Path FilterFillPath(Path path, Matrix ctm, int fillingRule) { path.CloseAllSubpaths(); Clipper clipper = new Clipper(); ClipperBridge.AddPath(clipper, path, PolyType.SUBJECT); foreach (Rectangle rectangle in regions) { Point[] transfRectVertices = TransformPoints(ctm, true, GetRectangleVertices(rectangle)); ClipperBridge.AddRectToClipper(clipper, transfRectVertices, PolyType.CLIP); } PolyFillType fillType = PolyFillType.NON_ZERO; if (fillingRule == PdfCanvasConstants.FillingRule.EVEN_ODD) { fillType = PolyFillType.EVEN_ODD; } PolyTree resultTree = new PolyTree(); clipper.Execute(ClipType.DIFFERENCE, resultTree, fillType, PolyFillType.NON_ZERO); return(ClipperBridge.ConvertToPath(resultTree)); }
/// <summary>Converts specified degenerate subpaths to squares.</summary> /// <remarks> /// Converts specified degenerate subpaths to squares. /// Note: the list of degenerate subpaths should contain at least 2 elements. Otherwise /// we can't determine the direction which the rotation of each square depends on. /// </remarks> /// <param name="squareWidth">Width of each constructed square.</param> /// <param name="sourcePath">The path which dash pattern applied to. Needed to calc rotation angle of each square. /// </param> /// <returns> /// /// <see cref="System.Collections.IList{E}"/> /// consisting of squares constructed on given degenerated subpaths. /// </returns> private static IList <Subpath> ConvertToSquares(IList <Subpath> degenerateSubpaths, double squareWidth, Path sourcePath) { IList <Point> pathApprox = GetPathApproximation(sourcePath); if (pathApprox.Count < 2) { return(JavaCollectionsUtil.EmptyList <Subpath>()); } IEnumerator <Point> approxIter = pathApprox.GetEnumerator(); approxIter.MoveNext(); Point approxPt1 = approxIter.Current; approxIter.MoveNext(); Point approxPt2 = approxIter.Current; PdfCleanUpFilter.StandardLine line = new PdfCleanUpFilter.StandardLine(approxPt1, approxPt2); IList <Subpath> squares = new List <Subpath>(degenerateSubpaths.Count); float widthHalf = (float)squareWidth / 2; foreach (Subpath subpath in degenerateSubpaths) { Point point = subpath.GetStartPoint(); while (!line.Contains(point)) { approxPt1 = approxPt2; approxIter.MoveNext(); approxPt2 = approxIter.Current; line = new PdfCleanUpFilter.StandardLine(approxPt1, approxPt2); } double slope = line.GetSlope(); double angle; if (!double.IsPositiveInfinity(slope)) { angle = Math.Atan(slope); } else { angle = Math.PI / 2; } squares.Add(ConstructSquare(point, widthHalf, angle)); } return(squares); }