33
44using System ;
55using System . Linq ;
6- using Clipper2Lib ;
6+ using System . Numerics ;
7+ using SixLabors . ImageSharp . Drawing . Shapes . PolygonClipper ;
78
89namespace SixLabors . ImageSharp . Drawing . PolygonClipper
910{
@@ -12,43 +13,40 @@ namespace SixLabors.ImageSharp.Drawing.PolygonClipper
1213 /// </summary>
1314 internal class ClipperOffset
1415 {
15- private const float ScalingFactor = 1000.0f ;
16-
17- private readonly Clipper2Lib . ClipperOffset innerClipperOffest ;
18- private readonly object syncRoot = new ( ) ;
16+ // To make the floating point polygons compatable with clipper we have to scale them.
17+ private const float ScalingFactor = 1000F ;
18+ private readonly PolygonOffsetter polygonClipperOffset ;
1919
2020 /// <summary>
2121 /// Initializes a new instance of the <see cref="ClipperOffset"/> class.
2222 /// </summary>
2323 /// <param name="meterLimit">meter limit</param>
2424 /// <param name="arcTolerance">arc tolerance</param>
2525 public ClipperOffset ( double meterLimit = 2 , double arcTolerance = 0.25 )
26- => this . innerClipperOffest = new Clipper2Lib . ClipperOffset ( meterLimit , arcTolerance ) ;
26+ => this . polygonClipperOffset = new ( ( float ) meterLimit , ( float ) arcTolerance ) ;
2727
2828 /// <summary>
29- /// Calcualte Offset
29+ /// Calculates an offset polygon based on the given path and width.
3030 /// </summary>
3131 /// <param name="width">Width</param>
3232 /// <returns>path offset</returns>
33- /// <exception cref="ClipperException">Calculate: Couldn't caculate Offset </exception>
33+ /// <exception cref="ClipperException">Calculate: Couldn't calculate the cffset. </exception>
3434 public ComplexPolygon Execute ( float width )
3535 {
36- Paths64 tree = new ( ) ;
37- lock ( this . syncRoot )
38- {
39- this . innerClipperOffest . Execute ( width * ScalingFactor , tree ) ;
40- }
36+ PathsF solution = new ( ) ;
37+ this . polygonClipperOffset . Execute ( width * ScalingFactor , solution ) ;
4138
42- var polygons = new Polygon [ tree . Count ] ;
43- for ( int i = 0 ; i < tree . Count ; i ++ )
39+ var polygons = new Polygon [ solution . Count ] ;
40+ const float scale = 1F / ScalingFactor ;
41+ for ( int i = 0 ; i < solution . Count ; i ++ )
4442 {
45- Path64 pt = tree [ i ] ;
43+ PathF pt = solution [ i ] ;
4644
47- PointF [ ] points = pt . Select ( p => new PointF ( p . X / ScalingFactor , p . Y / ScalingFactor ) ) . ToArray ( ) ;
45+ PointF [ ] points = pt . Select ( p => ( PointF ) ( p * scale ) ) . ToArray ( ) ;
4846 polygons [ i ] = new Polygon ( new LinearLineSegment ( points ) ) ;
4947 }
5048
51- return new ComplexPolygon ( polygons . ToArray ( ) ) ;
49+ return new ComplexPolygon ( polygons ) ;
5250 }
5351
5452 /// <summary>
@@ -58,8 +56,17 @@ public ComplexPolygon Execute(float width)
5856 /// <param name="jointStyle">Joint Style</param>
5957 /// <param name="endCapStyle">Endcap Style</param>
6058 /// <exception cref="ClipperException">AddPath: Invalid Path</exception>
61- public void AddPath ( ReadOnlySpan < PointF > pathPoints , JointStyle jointStyle , EndCapStyle endCapStyle ) =>
62- this . AddPath ( pathPoints , jointStyle , Convert ( endCapStyle ) ) ;
59+ public void AddPath ( ReadOnlySpan < PointF > pathPoints , JointStyle jointStyle , EndCapStyle endCapStyle )
60+ {
61+ PathF points = new ( pathPoints . Length ) ;
62+ for ( int i = 0 ; i < pathPoints . Length ; i ++ )
63+ {
64+ Vector2 v = pathPoints [ i ] ;
65+ points . Add ( v * ScalingFactor ) ;
66+ }
67+
68+ this . polygonClipperOffset . AddPath ( points , jointStyle , endCapStyle ) ;
69+ }
6370
6471 /// <summary>
6572 /// Adds the path.
@@ -87,46 +94,7 @@ public void AddPath(IPath path, JointStyle jointStyle, EndCapStyle endCapStyle)
8794 private void AddPath ( ISimplePath path , JointStyle jointStyle , EndCapStyle endCapStyle )
8895 {
8996 ReadOnlySpan < PointF > vectors = path . Points . Span ;
90- EndType type = path . IsClosed ? EndType . Joined : Convert ( endCapStyle ) ;
91- this . AddPath ( vectors , jointStyle , type ) ;
97+ this . AddPath ( vectors , jointStyle , path . IsClosed ? EndCapStyle . Joined : endCapStyle ) ;
9298 }
93-
94- /// <summary>
95- /// Adds the path.
96- /// </summary>
97- /// <param name="pathPoints">The path points</param>
98- /// <param name="jointStyle">Joint Style</param>
99- /// <param name="endCapStyle">Endcap Style</param>
100- /// <exception cref="ClipperException">AddPath: Invalid Path</exception>
101- private void AddPath ( ReadOnlySpan < PointF > pathPoints , JointStyle jointStyle , EndType endCapStyle )
102- {
103- Path64 points = new ( ) ;
104- foreach ( PointF v in pathPoints )
105- {
106- points . Add ( new Point64 ( v . X * ScalingFactor , v . Y * ScalingFactor ) ) ;
107- }
108-
109- // TODO: Why are we locking?
110- lock ( this . syncRoot )
111- {
112- this . innerClipperOffest . AddPath ( points , Convert ( jointStyle ) , endCapStyle ) ;
113- }
114- }
115-
116- private static JoinType Convert ( JointStyle style )
117- => style switch
118- {
119- JointStyle . Round => JoinType . Round ,
120- JointStyle . Miter => JoinType . Miter ,
121- _ => JoinType . Square ,
122- } ;
123-
124- private static EndType Convert ( EndCapStyle style )
125- => style switch
126- {
127- EndCapStyle . Round => EndType . Round ,
128- EndCapStyle . Square => EndType . Square ,
129- _ => EndType . Butt ,
130- } ;
13199 }
132100}
0 commit comments