|
1 | 1 | // Copyright (c) Six Labors.
|
2 | 2 | // Licensed under the Six Labors Split License.
|
3 | 3 |
|
| 4 | +using SixLabors.PolygonClipper; |
| 5 | + |
4 | 6 | namespace SixLabors.ImageSharp.Drawing.Shapes.PolygonClipper;
|
5 | 7 |
|
6 | 8 | /// <summary>
|
7 | 9 | /// Library to clip polygons.
|
8 | 10 | /// </summary>
|
9 | 11 | internal class Clipper
|
10 | 12 | {
|
11 |
| - private readonly PolygonClipper polygonClipper; |
12 |
| - |
13 |
| - /// <summary> |
14 |
| - /// Initializes a new instance of the <see cref="Clipper"/> class. |
15 |
| - /// </summary> |
16 |
| - public Clipper() |
17 |
| - => this.polygonClipper = new PolygonClipper(); |
| 13 | + private SixLabors.PolygonClipper.Polygon? subject; |
| 14 | + private SixLabors.PolygonClipper.Polygon? clip; |
18 | 15 |
|
19 | 16 | /// <summary>
|
20 | 17 | /// Generates the clipped shapes from the previously provided paths.
|
21 | 18 | /// </summary>
|
22 | 19 | /// <param name="operation">The clipping operation.</param>
|
23 | 20 | /// <param name="rule">The intersection rule.</param>
|
24 | 21 | /// <returns>The <see cref="T:IPath[]"/>.</returns>
|
25 |
| - public IPath[] GenerateClippedShapes(ClippingOperation operation, IntersectionRule rule) |
| 22 | + public IPath[] GenerateClippedShapes(BooleanOperation operation) |
26 | 23 | {
|
27 |
| - PathsF closedPaths = []; |
28 |
| - PathsF openPaths = []; |
| 24 | + ArgumentNullException.ThrowIfNull(this.subject); |
| 25 | + ArgumentNullException.ThrowIfNull(this.clip); |
29 | 26 |
|
30 |
| - FillRule fillRule = rule == IntersectionRule.EvenOdd ? FillRule.EvenOdd : FillRule.NonZero; |
31 |
| - this.polygonClipper.Execute(operation, fillRule, closedPaths, openPaths); |
| 27 | + SixLabors.PolygonClipper.PolygonClipper polygonClipper = new(this.subject, this.clip, operation); |
32 | 28 |
|
33 |
| - IPath[] shapes = new IPath[closedPaths.Count + openPaths.Count]; |
| 29 | + SixLabors.PolygonClipper.Polygon result = polygonClipper.Run(); |
34 | 30 |
|
35 |
| - int index = 0; |
36 |
| - for (int i = 0; i < closedPaths.Count; i++) |
37 |
| - { |
38 |
| - PathF path = closedPaths[i]; |
39 |
| - PointF[] points = new PointF[path.Count]; |
40 | 31 |
|
41 |
| - for (int j = 0; j < path.Count; j++) |
42 |
| - { |
43 |
| - points[j] = path[j]; |
44 |
| - } |
| 32 | + IPath[] shapes = new IPath[result.Count]; |
45 | 33 |
|
46 |
| - shapes[index++] = new Polygon(points); |
47 |
| - } |
48 |
| - |
49 |
| - for (int i = 0; i < openPaths.Count; i++) |
| 34 | + int index = 0; |
| 35 | + for (int i = 0; i < result.Count; i++) |
50 | 36 | {
|
51 |
| - PathF path = openPaths[i]; |
52 |
| - PointF[] points = new PointF[path.Count]; |
| 37 | + Contour contour = result[i]; |
| 38 | + PointF[] points = new PointF[contour.Count]; |
53 | 39 |
|
54 |
| - for (int j = 0; j < path.Count; j++) |
| 40 | + for (int j = 0; j < contour.Count; j++) |
55 | 41 | {
|
56 |
| - points[j] = path[j]; |
| 42 | + Vertex vertex = contour[j]; |
| 43 | + points[j] = new PointF((float)vertex.X, (float)vertex.Y); |
57 | 44 | }
|
58 | 45 |
|
59 | 46 | shapes[index++] = new Polygon(points);
|
@@ -100,12 +87,25 @@ public void AddPath(IPath path, ClippingType clippingType)
|
100 | 87 | internal void AddPath(ISimplePath path, ClippingType clippingType)
|
101 | 88 | {
|
102 | 89 | ReadOnlySpan<PointF> vectors = path.Points.Span;
|
103 |
| - PathF points = new(vectors.Length); |
104 |
| - for (int i = 0; i < vectors.Length; i++) |
| 90 | + SixLabors.PolygonClipper.Polygon polygon = []; |
| 91 | + Contour contour = new(); |
| 92 | + polygon.Add(contour); |
| 93 | + |
| 94 | + foreach (PointF point in vectors) |
105 | 95 | {
|
106 |
| - points.Add(vectors[i]); |
| 96 | + contour.AddVertex(new Vertex(point.X, point.Y)); |
107 | 97 | }
|
108 | 98 |
|
109 |
| - this.polygonClipper.AddPath(points, clippingType, !path.IsClosed); |
| 99 | + switch (clippingType) |
| 100 | + { |
| 101 | + case ClippingType.Clip: |
| 102 | + this.clip = polygon; |
| 103 | + break; |
| 104 | + case ClippingType.Subject: |
| 105 | + this.subject = polygon; |
| 106 | + break; |
| 107 | + default: |
| 108 | + throw new ArgumentOutOfRangeException(nameof(clippingType), clippingType, null); |
| 109 | + } |
110 | 110 | }
|
111 | 111 | }
|
0 commit comments