diff --git a/src/SixLabors.Shapes/ClipperExtensions.cs b/src/SixLabors.Shapes/ClipperExtensions.cs index 7521280..71d13c1 100644 --- a/src/SixLabors.Shapes/ClipperExtensions.cs +++ b/src/SixLabors.Shapes/ClipperExtensions.cs @@ -16,15 +16,16 @@ public static class ClipperExtensions /// /// The shape. /// The holes. + /// The fillType. /// Returns a new shape with the holes cliped out out the shape. - public static IPath Clip(this IPath shape, IEnumerable holes) + public static IPath Clip(this IPath shape, IEnumerable holes, FillType fillType = FillType.EvenOdd) { var clipper = new Clipper(); clipper.AddPath(shape, ClippingType.Subject); clipper.AddPaths(holes, ClippingType.Clip); - IPath[] result = clipper.GenerateClippedShapes(); + IPath[] result = clipper.GenerateClippedShapes(fillType); return new ComplexPolygon(result); } diff --git a/src/SixLabors.Shapes/FillType.cs b/src/SixLabors.Shapes/FillType.cs new file mode 100644 index 0000000..a7dcf25 --- /dev/null +++ b/src/SixLabors.Shapes/FillType.cs @@ -0,0 +1,31 @@ +// Copyright (c) Six Labors and contributors. +// Licensed under the Apache License, Version 2.0. + +namespace SixLabors.Shapes +{ + /// + /// The fill type method used when filling a polygon. + /// + public enum FillType + { + /// + /// Even-Odd rule. + /// + EvenOdd = 0, + + /// + /// Non-Zero rule. + /// + NonZero = 1, + + /// + /// Positive rule. + /// + Positive = 2, + + /// + /// Negative rule. + /// + Negative = 3, + } +} \ No newline at end of file diff --git a/src/SixLabors.Shapes/PolygonClipper/Clipper.cs b/src/SixLabors.Shapes/PolygonClipper/Clipper.cs index 5f5cbb6..72b54e4 100644 --- a/src/SixLabors.Shapes/PolygonClipper/Clipper.cs +++ b/src/SixLabors.Shapes/PolygonClipper/Clipper.cs @@ -40,16 +40,17 @@ public Clipper(params ClippablePath[] shapes) /// /// Executes the specified clip type. /// + /// The fillType. /// /// Returns the array containing the converted polygons. /// - public IPath[] GenerateClippedShapes() + public IPath[] GenerateClippedShapes(FillType fillType = FillType.EvenOdd) { var results = new List(); lock (this.syncRoot) { - this.innerClipper.Execute(ClipType.ctDifference, results); + this.innerClipper.Execute(ClipType.ctDifference, results, Convert(fillType)); } var shapes = new IPath[results.Count]; @@ -153,5 +154,21 @@ internal void AddPath(ISimplePath path, ClippingType clippingType) this.innerClipper.AddPath(points, type, path.IsClosed); } } + + private static PolyFillType Convert(FillType type) + { + switch (type) + { + case FillType.NonZero: + return PolyFillType.pftNonZero; + case FillType.Positive: + return PolyFillType.pftPositive; + case FillType.Negative: + return PolyFillType.pftNegative; + case FillType.EvenOdd: + default: + return PolyFillType.pftEvenOdd; + } + } } } \ No newline at end of file