Skip to content

Commit 4bfa88b

Browse files
committed
Add methods on PolygonStroker for manually composing (line) paths
1 parent 0285e5d commit 4bfa88b

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

src/ImageSharp.Drawing/Shapes/PolygonClipper/PolygonStroker.cs

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,42 @@ public double Width
5353
}
5454
}
5555

56-
public PathF ProcessPath(ReadOnlySpan<PointF> pathPoints, bool isClosed)
56+
public PathF ProcessPath(ReadOnlySpan<PointF> linePoints, bool isClosed)
5757
{
5858
this.Reset();
59-
for (int i = 0; i < pathPoints.Length; i++)
59+
this.AddLinePath(linePoints);
60+
61+
if (isClosed)
6062
{
61-
PointF point = pathPoints[i];
62-
this.AddVertex(point.X, point.Y, PathCommand.LineTo);
63+
this.ClosePath();
6364
}
6465

65-
if (isClosed)
66+
PathF results = new(linePoints.Length * 3);
67+
this.FinishPath(results);
68+
return results;
69+
}
70+
71+
public void AddLinePath(ReadOnlySpan<PointF> linePoints)
72+
{
73+
for (int i = 0; i < linePoints.Length; i++)
6674
{
67-
this.AddVertex(0, 0, PathCommand.EndPoly | (PathCommand)PathFlags.Close);
75+
PointF point = linePoints[i];
76+
this.AddVertex(point.X, point.Y, PathCommand.LineTo);
6877
}
78+
}
79+
80+
public void ClosePath()
81+
{
82+
this.AddVertex(0, 0, PathCommand.EndPoly | (PathCommand)PathFlags.Close);
83+
}
6984

85+
public void FinishPath(List<PointF> results)
86+
{
7087
PointF currentPoint = new(0, 0);
7188
int startIndex = 0;
7289
PointF? lastPoint = null;
7390
PathCommand command;
7491

75-
PathF results = new(pathPoints.Length * 3);
7692
while (!(command = this.Accumulate(ref currentPoint)).Stop())
7793
{
7894
if (command.EndPoly() && results.Count > 0)
@@ -90,12 +106,9 @@ public PathF ProcessPath(ReadOnlySpan<PointF> pathPoints, bool isClosed)
90106
}
91107
}
92108
}
93-
94-
return results;
95109
}
96110

97-
[MethodImpl(MethodImplOptions.AggressiveInlining)]
98-
private void Reset()
111+
public void Reset()
99112
{
100113
this.srcVertices.Clear();
101114
this.outVertices.Clear();

tests/ImageSharp.Drawing.Benchmarks/Drawing/DrawPolygon.cs

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -211,30 +211,52 @@ public void Blaze()
211211

212212
private static List<List<PointF>> GenerateOutlineList(IPath path, float width, JointStyle jointStyle, EndCapStyle endCapStyle)
213213
{
214+
List<List<PointF>> strokedLines = [];
215+
214216
if (width <= 0)
215217
{
216-
return [];
218+
return strokedLines;
217219
}
218220

219-
List<List<PointF>> stroked = [];
220-
221-
PolygonStroker stroker = new() { Width = width, LineJoin = GetLineJoin(jointStyle), LineCap = GetLineCap(endCapStyle) };
221+
PolygonStroker stroker = new()
222+
{
223+
Width = width,
224+
LineJoin = GetLineJoin(jointStyle),
225+
LineCap = GetLineCap(endCapStyle)
226+
};
222227
foreach (ISimplePath simplePath in path.Flatten())
223228
{
224-
bool isClosed = simplePath.IsClosed || endCapStyle is EndCapStyle.Polygon or EndCapStyle.Joined;
229+
stroker.Reset();
230+
231+
int pointCount = 0;
225232
if (simplePath is Path concretePath)
226233
{
227-
if (concretePath.LineSegments.Count == 1 && concretePath.LineSegments[0] is LinearLineSegment lineSegment)
234+
foreach (ILineSegment line in concretePath.LineSegments)
228235
{
229-
stroked.Add(stroker.ProcessPath(lineSegment.Flatten().Span, isClosed));
230-
continue;
236+
ReadOnlySpan<PointF> points = line.Flatten().Span;
237+
stroker.AddLinePath(points);
238+
pointCount += points.Length;
231239
}
232240
}
241+
else
242+
{
243+
ReadOnlySpan<PointF> points = simplePath.Points.Span;
244+
stroker.AddLinePath(points);
245+
pointCount = points.Length;
246+
}
247+
248+
bool isClosed = simplePath.IsClosed || endCapStyle is EndCapStyle.Polygon or EndCapStyle.Joined;
249+
if (isClosed)
250+
{
251+
stroker.ClosePath();
252+
}
233253

234-
stroked.Add(stroker.ProcessPath(simplePath.Points.Span, isClosed));
254+
List<PointF> lineBuilder = new(pointCount * 4);
255+
stroker.FinishPath(lineBuilder);
256+
strokedLines.Add(lineBuilder);
235257
}
236258

237-
return stroked;
259+
return strokedLines;
238260

239261
static LineJoin GetLineJoin(JointStyle value) => value switch
240262
{

0 commit comments

Comments
 (0)