Skip to content

Commit 4561a3c

Browse files
Add hacked AGG stroker
1 parent 16d79e7 commit 4561a3c

16 files changed

Lines changed: 1199 additions & 63 deletions

File tree

.editorconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,8 @@ dotnet_diagnostic.IDE0063.severity = suggestion
172172
csharp_using_directive_placement = outside_namespace:warning
173173
# Modifier preferences
174174
csharp_prefer_static_local_function = true:warning
175+
# Primary constructor preferences
176+
csharp_style_prefer_primary_constructors = false:none
175177

176178
##########################################
177179
# Unnecessary Code Rules

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,3 +133,6 @@
133133
*.pnm filter=lfs diff=lfs merge=lfs -text
134134
*.wbmp filter=lfs diff=lfs merge=lfs -text
135135
*.exr filter=lfs diff=lfs merge=lfs -text
136+
*.ico filter=lfs diff=lfs merge=lfs -text
137+
*.cur filter=lfs diff=lfs merge=lfs -text
138+
*.ani filter=lfs diff=lfs merge=lfs -text

samples/DrawShapesWithImageSharp/DrawShapesWithImageSharp.csproj

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88
<Choose>
99
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
1010
<PropertyGroup>
11-
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
11+
<TargetFrameworks>net8.0</TargetFrameworks>
1212
</PropertyGroup>
1313
</When>
1414
<Otherwise>
1515
<PropertyGroup>
16-
<TargetFrameworks>net6.0</TargetFrameworks>
16+
<TargetFrameworks>net8.0</TargetFrameworks>
1717
</PropertyGroup>
1818
</Otherwise>
1919
</Choose>

src/ImageSharp.Drawing/ImageSharp.Drawing.csproj

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,27 @@
1414
<Configurations>Debug;Release</Configurations>
1515
</PropertyGroup>
1616

17-
<PropertyGroup>
18-
<!--Bump to V2 prior to tagged release.-->
19-
<MinVerMinimumMajorMinor>2.0</MinVerMinimumMajorMinor>
20-
</PropertyGroup>
21-
2217
<!-- This enables the nullable analysis and treats all nullable warnings as error-->
2318
<PropertyGroup>
2419
<Nullable>enable</Nullable>
2520
<WarningsAsErrors>Nullable</WarningsAsErrors>
2621
</PropertyGroup>
22+
23+
<PropertyGroup>
24+
<!--Bump to V3 prior to tagged release.-->
25+
<MinVerMinimumMajorMinor>3.0</MinVerMinimumMajorMinor>
26+
</PropertyGroup>
2727

2828
<Choose>
2929
<When Condition="$(SIXLABORS_TESTING_PREVIEW) == true">
3030
<PropertyGroup>
31-
<TargetFrameworks>net7.0;net6.0</TargetFrameworks>
31+
<TargetFrameworks>net8.0</TargetFrameworks>
3232
<IsTrimmable>true</IsTrimmable>
3333
</PropertyGroup>
3434
</When>
3535
<Otherwise>
3636
<PropertyGroup>
37-
<TargetFrameworks>net6.0</TargetFrameworks>
37+
<TargetFrameworks>net8.0</TargetFrameworks>
3838
<IsTrimmable>true</IsTrimmable>
3939
</PropertyGroup>
4040
</Otherwise>
@@ -46,7 +46,7 @@
4646
</ItemGroup>
4747
<ItemGroup>
4848
<PackageReference Include="SixLabors.Fonts" Version="2.0.1" />
49-
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.1" />
49+
<PackageReference Include="SixLabors.ImageSharp" Version="4.0.0-alpha.0.7" />
5050
</ItemGroup>
5151
<Import Project="..\..\shared-infrastructure\src\SharedInfrastructure\SharedInfrastructure.projitems" Label="Shared" />
5252
</Project>

src/ImageSharp.Drawing/Processing/PathGradientBrush.cs

Lines changed: 5 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,11 @@ public sealed class PathGradientBrush : Brush
2222
/// <param name="colors">Array of colors that correspond to each point in the polygon.</param>
2323
public PathGradientBrush(PointF[] points, Color[] colors)
2424
{
25-
if (points == null)
26-
{
27-
throw new ArgumentNullException(nameof(points));
28-
}
29-
30-
if (points.Length < 3)
31-
{
32-
throw new ArgumentOutOfRangeException(
33-
nameof(points),
34-
"There must be at least 3 lines to construct a path gradient brush.");
35-
}
25+
Guard.NotNull(points, nameof(points));
26+
Guard.MustBeGreaterThanOrEqualTo(points.Length, 3, nameof(points));
3627

37-
if (colors == null)
38-
{
39-
throw new ArgumentNullException(nameof(colors));
40-
}
41-
42-
if (colors.Length == 0)
43-
{
44-
throw new ArgumentOutOfRangeException(
45-
nameof(colors),
46-
"One or more color is needed to construct a path gradient brush.");
47-
}
28+
Guard.NotNull(colors, nameof(colors));
29+
Guard.MustBeGreaterThan(colors.Length, 0, nameof(colors));
4830

4931
int size = points.Length;
5032

@@ -105,21 +87,7 @@ public override BrushApplicator<TPixel> CreateApplicator<TPixel>(
10587
this.hasSpecialCenterColor);
10688

10789
private static Color CalculateCenterColor(Color[] colors)
108-
{
109-
if (colors == null)
110-
{
111-
throw new ArgumentNullException(nameof(colors));
112-
}
113-
114-
if (colors.Length == 0)
115-
{
116-
throw new ArgumentOutOfRangeException(
117-
nameof(colors),
118-
"One or more color is needed to construct a path gradient brush.");
119-
}
120-
121-
return new Color(colors.Select(c => (Vector4)c).Aggregate((p1, p2) => p1 + p2) / colors.Length);
122-
}
90+
=> new(colors.Select(c => (Vector4)c).Aggregate((p1, p2) => p1 + p2) / colors.Length);
12391

12492
private static float DistanceBetween(Vector2 p1, Vector2 p2) => (p2 - p1).Length();
12593

src/ImageSharp.Drawing/Shapes/EndCapStyle.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,3 +33,10 @@ public enum EndCapStyle
3333
/// </summary>
3434
Joined = 4
3535
}
36+
37+
internal enum LineCap
38+
{
39+
Butt,
40+
Square,
41+
Round
42+
}

src/ImageSharp.Drawing/Shapes/JointStyle.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,20 @@ public enum JointStyle
2323
/// </summary>
2424
Miter = 2
2525
}
26+
27+
internal enum LineJoin
28+
{
29+
MiterJoin = 0,
30+
MiterJoinRevert = 1,
31+
RoundJoin = 2,
32+
BevelJoin = 3,
33+
MiterJoinRound = 4
34+
}
35+
36+
internal enum InnerJoin
37+
{
38+
InnerBevel,
39+
InnerMiter,
40+
InnerJag,
41+
InnerRound
42+
}

src/ImageSharp.Drawing/Shapes/OutlinePathExtensions.cs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,17 +34,31 @@ public static IPath GenerateOutline(this IPath path, float width)
3434
/// <param name="endCapStyle">The style to apply to the end caps.</param>
3535
/// <returns>A new <see cref="IPath"/> representing the outline.</returns>
3636
/// <exception cref="ClipperException">Thrown when an offset cannot be calculated.</exception>
37+
#pragma warning disable RCS1163 // Unused parameter
38+
#pragma warning disable IDE0060 // Remove unused parameter
3739
public static IPath GenerateOutline(this IPath path, float width, JointStyle jointStyle, EndCapStyle endCapStyle)
40+
#pragma warning restore IDE0060 // Remove unused parameter
41+
#pragma warning restore RCS1163 // Unused parameter
3842
{
3943
if (width <= 0)
4044
{
4145
return Path.Empty;
4246
}
4347

44-
ClipperOffset offset = new(MiterOffsetDelta);
45-
offset.AddPath(path, jointStyle, endCapStyle);
48+
List<Polygon> polygons = [];
49+
foreach (ISimplePath simplePath in path.Flatten())
50+
{
51+
PolygonStroker stroker = new();
52+
Polygon polygon = stroker.ProcessPath(simplePath.Points.Span);
53+
polygons.Add(polygon);
54+
}
4655

47-
return offset.Execute(width);
56+
return new ComplexPolygon(polygons);
57+
58+
// ClipperOffset offset = new(MiterOffsetDelta);
59+
// offset.AddPath(path, jointStyle, endCapStyle);
60+
61+
// return offset.Execute(width);
4862
}
4963

5064
/// <summary>
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
// Copyright (c) Six Labors.
2+
// Licensed under the Six Labors Split License.
3+
4+
using System.Runtime.CompilerServices;
5+
6+
namespace SixLabors.ImageSharp.Drawing.Shapes.PolygonClipper;
7+
8+
/// <summary>
9+
/// A helper type for avoiding allocations while building arrays.
10+
/// </summary>
11+
/// <typeparam name="T">The type of item contained in the array.</typeparam>
12+
internal struct ArrayBuilder<T>
13+
where T : struct
14+
{
15+
private const int DefaultCapacity = 4;
16+
private const int MaxCoreClrArrayLength = 0x7FeFFFFF;
17+
18+
// Starts out null, initialized on first Add.
19+
private T[]? data;
20+
private int size;
21+
22+
/// <summary>
23+
/// Initializes a new instance of the <see cref="ArrayBuilder{T}"/> struct.
24+
/// </summary>
25+
/// <param name="capacity">The initial capacity of the array.</param>
26+
public ArrayBuilder(int capacity)
27+
: this()
28+
{
29+
Guard.MustBeGreaterThanOrEqualTo(capacity, 0, nameof(capacity));
30+
31+
this.data = new T[capacity];
32+
this.size = capacity;
33+
}
34+
35+
/// <summary>
36+
/// Gets or sets the number of items in the array.
37+
/// </summary>
38+
public int Length
39+
{
40+
readonly get => this.size;
41+
42+
set
43+
{
44+
if (value != this.size)
45+
{
46+
if (value > 0)
47+
{
48+
this.EnsureCapacity(value);
49+
this.size = value;
50+
}
51+
else
52+
{
53+
this.size = 0;
54+
}
55+
}
56+
}
57+
}
58+
59+
/// <summary>
60+
/// Returns a reference to specified element of the array.
61+
/// </summary>
62+
/// <param name="index">The index of the element to return.</param>
63+
/// <returns>The <typeparamref name="T"/>.</returns>
64+
/// <exception cref="IndexOutOfRangeException">
65+
/// Thrown when index less than 0 or index greater than or equal to <see cref="Length"/>.
66+
/// </exception>
67+
public readonly ref T this[int index]
68+
{
69+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
70+
get
71+
{
72+
DebugGuard.MustBeBetweenOrEqualTo(index, 0, this.size, nameof(index));
73+
return ref this.data![index];
74+
}
75+
}
76+
77+
/// <summary>
78+
/// Adds the given item to the array.
79+
/// </summary>
80+
/// <param name="item">The item to add.</param>
81+
public void Add(T item)
82+
{
83+
int position = this.size;
84+
85+
// Expand the array.
86+
this.Length++;
87+
this.data![position] = item;
88+
}
89+
90+
/// <summary>
91+
/// Remove the last item from the array.
92+
/// </summary>
93+
public void RemoveLast()
94+
{
95+
DebugGuard.MustBeGreaterThan(this.size, 0, nameof(this.size));
96+
this.size--;
97+
}
98+
99+
/// <summary>
100+
/// Clears the array.
101+
/// Allocated memory is left intact for future usage.
102+
/// </summary>
103+
public void Clear() =>
104+
105+
// No need to actually clear since we're not allowing reference types.
106+
this.size = 0;
107+
108+
private void EnsureCapacity(int min)
109+
{
110+
int length = this.data?.Length ?? 0;
111+
if (length < min)
112+
{
113+
// Same expansion algorithm as List<T>.
114+
uint newCapacity = length == 0 ? DefaultCapacity : (uint)length * 2u;
115+
if (newCapacity > MaxCoreClrArrayLength)
116+
{
117+
newCapacity = MaxCoreClrArrayLength;
118+
}
119+
120+
if (newCapacity < min)
121+
{
122+
newCapacity = (uint)min;
123+
}
124+
125+
T[] array = new T[newCapacity];
126+
127+
if (this.size > 0)
128+
{
129+
Array.Copy(this.data!, array, this.size);
130+
}
131+
132+
this.data = array;
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)