Skip to content

Commit 087f480

Browse files
Wire up factory
1 parent 6c6ff30 commit 087f480

File tree

5 files changed

+410
-52
lines changed

5 files changed

+410
-52
lines changed

src/ImageSharp.Drawing/Shapes/ClipPathExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,12 @@ public static IPath Clip(
5858
ShapeOptions options,
5959
IEnumerable<IPath> clipPaths)
6060
{
61-
Clipper clipper = new();
61+
Clipper clipper = new(options.IntersectionRule);
6262

6363
clipper.AddPath(subjectPath, ClippingType.Subject);
6464
clipper.AddPaths(clipPaths, ClippingType.Clip);
6565

66-
IPath[] result = clipper.GenerateClippedShapes(options.ClippingOperation, options.IntersectionRule);
66+
IPath[] result = clipper.GenerateClippedShapes(options.ClippingOperation);
6767

6868
return new ComplexPolygon(result);
6969
}

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

Lines changed: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,39 @@
22
// Licensed under the Six Labors Split License.
33

44
using SixLabors.PolygonClipper;
5+
using ClipperPolygon = SixLabors.PolygonClipper.Polygon;
6+
using PolygonClipperAction = SixLabors.PolygonClipper.PolygonClipper;
57

68
namespace SixLabors.ImageSharp.Drawing.Shapes.PolygonClipper;
79

810
/// <summary>
9-
/// Library to clip polygons.
11+
/// Performs polygon clipping operations.
1012
/// </summary>
11-
internal class Clipper
13+
internal sealed class Clipper
1214
{
13-
private SixLabors.PolygonClipper.Polygon? subject;
14-
private SixLabors.PolygonClipper.Polygon? clip;
15+
private ClipperPolygon? subject;
16+
private ClipperPolygon? clip;
17+
private readonly IntersectionRule rule;
18+
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="Clipper"/> class.
21+
/// </summary>
22+
/// <param name="rule">The intersection rule.</param>
23+
public Clipper(IntersectionRule rule) => this.rule = rule;
1524

1625
/// <summary>
1726
/// Generates the clipped shapes from the previously provided paths.
1827
/// </summary>
1928
/// <param name="operation">The clipping operation.</param>
20-
/// <param name="rule">The intersection rule.</param>
2129
/// <returns>The <see cref="T:IPath[]"/>.</returns>
22-
public IPath[] GenerateClippedShapes(BooleanOperation operation, IntersectionRule rule)
30+
public IPath[] GenerateClippedShapes(BooleanOperation operation)
2331
{
2432
ArgumentNullException.ThrowIfNull(this.subject);
2533
ArgumentNullException.ThrowIfNull(this.clip);
2634

27-
SixLabors.PolygonClipper.PolygonClipper polygonClipper = new(this.subject, this.clip, operation);
35+
PolygonClipperAction polygonClipper = new(this.subject, this.clip, operation);
2836

29-
SixLabors.PolygonClipper.Polygon result = polygonClipper.Run();
37+
ClipperPolygon result = polygonClipper.Run();
3038

3139
IPath[] shapes = new IPath[result.Count];
3240

@@ -49,17 +57,29 @@ public IPath[] GenerateClippedShapes(BooleanOperation operation, IntersectionRul
4957
}
5058

5159
/// <summary>
52-
/// Adds the shapes.
60+
/// Adds the collection of paths.
5361
/// </summary>
5462
/// <param name="paths">The paths.</param>
5563
/// <param name="clippingType">The clipping type.</param>
5664
public void AddPaths(IEnumerable<IPath> paths, ClippingType clippingType)
5765
{
5866
Guard.NotNull(paths, nameof(paths));
5967

60-
foreach (IPath p in paths)
68+
// Accumulate all paths of the complex shape into a single polygon.
69+
ClipperPolygon polygon = [];
70+
71+
foreach (IPath path in paths)
6172
{
62-
this.AddPath(p, clippingType);
73+
polygon = PolygonClipperFactory.FromSimplePaths(path.Flatten(), this.rule, polygon);
74+
}
75+
76+
if (clippingType == ClippingType.Clip)
77+
{
78+
this.clip = polygon;
79+
}
80+
else
81+
{
82+
this.subject = polygon;
6383
}
6484
}
6585

@@ -72,31 +92,14 @@ public void AddPath(IPath path, ClippingType clippingType)
7292
{
7393
Guard.NotNull(path, nameof(path));
7494

75-
foreach (ISimplePath p in path.Flatten())
95+
ClipperPolygon polygon = PolygonClipperFactory.FromSimplePaths(path.Flatten(), this.rule);
96+
if (clippingType == ClippingType.Clip)
7697
{
77-
this.AddPath(p, clippingType);
98+
this.clip = polygon;
7899
}
79-
}
80-
81-
/// <summary>
82-
/// Adds the path.
83-
/// </summary>
84-
/// <param name="path">The path.</param>
85-
/// <param name="clippingType">Type of the poly.</param>
86-
internal void AddPath(ISimplePath path, ClippingType clippingType)
87-
{
88-
SixLabors.PolygonClipper.Polygon polygon = path.ToPolygon();
89-
90-
switch (clippingType)
100+
else
91101
{
92-
case ClippingType.Clip:
93-
this.clip = polygon;
94-
break;
95-
case ClippingType.Subject:
96-
this.subject = polygon;
97-
break;
98-
default:
99-
throw new ArgumentOutOfRangeException(nameof(clippingType), clippingType, null);
102+
this.subject = polygon;
100103
}
101104
}
102105
}

0 commit comments

Comments
 (0)