Skip to content

Commit c221b81

Browse files
committed
remove OrientationHandling
1 parent 3ff3e59 commit c221b81

File tree

3 files changed

+22
-54
lines changed

3 files changed

+22
-54
lines changed

src/ImageSharp.Drawing/Shapes/OrientationHandling.cs

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/ImageSharp.Drawing/Shapes/Rasterization/ScanEdgeCollection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public static ScanEdgeCollection Create(
4242
MemoryAllocator allocator,
4343
int subsampling)
4444
{
45-
TessellatedMultipolygon multipolygon = TessellatedMultipolygon.Create(polygon, allocator, OrientationHandling.ForcePositiveOrientationOnSimplePolygons);
45+
TessellatedMultipolygon multipolygon = TessellatedMultipolygon.Create(polygon, allocator);
4646
return Create(multipolygon, allocator, subsampling);
4747
}
4848
}

src/ImageSharp.Drawing/Shapes/TessellatedMultipolygon.cs

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -28,47 +28,32 @@ private TessellatedMultipolygon(Ring[] rings)
2828
this.TotalVertexCount = rings.Sum(r => r.VertexCount);
2929
}
3030

31-
private enum RingType
32-
{
33-
Contour,
34-
Hole
35-
}
36-
3731
public int TotalVertexCount { get; }
3832

3933
public int Count => this.rings.Length;
4034

4135
public Ring this[int index] => this.rings[index];
4236

43-
public static TessellatedMultipolygon Create(
44-
IPath path,
45-
MemoryAllocator memoryAllocator,
46-
OrientationHandling orientationHandling = OrientationHandling.ForcePositiveOrientationOnSimplePolygons)
37+
public static TessellatedMultipolygon Create(IPath path, MemoryAllocator memoryAllocator)
4738
{
48-
RingType? firstRingType = orientationHandling == OrientationHandling.FirstRingIsContourFollowedByHoles ? RingType.Contour : (RingType?)null;
49-
RingType? followUpRingType = orientationHandling == OrientationHandling.FirstRingIsContourFollowedByHoles ? RingType.Hole : (RingType?)null;
50-
51-
// For now let's go with the assumption that first loop is always an external contour,
52-
// and the rests are loops.
5339
if (path is IInternalPathOwner ipo)
5440
{
5541
IReadOnlyList<InternalPath> internalPaths = ipo.GetRingsAsInternalPath();
5642

57-
// If we have only one ring, we may want to orient it as a contour
58-
if (internalPaths.Count == 1 && orientationHandling != OrientationHandling.KeepOriginal)
59-
{
60-
firstRingType = RingType.Contour;
61-
}
43+
// If we have only one ring, we can change it's orientation without negative side-effects.
44+
// Since the algorithm works best with positively-oriented polygons,
45+
// we enforce the orientation for best output quality.
46+
bool enforcePositiveOrientationOnFirstRing = internalPaths.Count == 1;
6247

63-
Ring[] rings = new Ring[internalPaths.Count];
48+
var rings = new Ring[internalPaths.Count];
6449
IMemoryOwner<PointF> pointBuffer = internalPaths[0].ExtractVertices(memoryAllocator);
65-
RepeateFirstVertexAndEnsureOrientation(pointBuffer.Memory.Span, firstRingType);
50+
RepeateFirstVertexAndEnsureOrientation(pointBuffer.Memory.Span, enforcePositiveOrientationOnFirstRing);
6651
rings[0] = new Ring(pointBuffer);
6752

6853
for (int i = 1; i < internalPaths.Count; i++)
6954
{
7055
pointBuffer = internalPaths[i].ExtractVertices(memoryAllocator);
71-
RepeateFirstVertexAndEnsureOrientation(pointBuffer.Memory.Span, followUpRingType);
56+
RepeateFirstVertexAndEnsureOrientation(pointBuffer.Memory.Span, false);
7257
rings[i] = new Ring(pointBuffer);
7358
}
7459

@@ -78,40 +63,38 @@ public static TessellatedMultipolygon Create(
7863
{
7964
ReadOnlyMemory<PointF>[] points = path.Flatten().Select(sp => sp.Points).ToArray();
8065

81-
// If we have only one ring, we may want to orient it as a contour
82-
if (points.Length == 1 && orientationHandling != OrientationHandling.KeepOriginal)
83-
{
84-
firstRingType = RingType.Contour;
85-
}
66+
// If we have only one ring, we can change it's orientation without negative side-effects.
67+
// Since the algorithm works best with positively-oriented polygons,
68+
// we enforce the orientation for best output quality.
69+
bool enforcePositiveOrientationOnFirstRing = points.Length == 1;
8670

87-
Ring[] rings = new Ring[points.Length];
88-
rings[0] = MakeRing(points[0], firstRingType, memoryAllocator);
71+
var rings = new Ring[points.Length];
72+
rings[0] = MakeRing(points[0], enforcePositiveOrientationOnFirstRing, memoryAllocator);
8973
for (int i = 1; i < points.Length; i++)
9074
{
91-
rings[i] = MakeRing(points[i], followUpRingType, memoryAllocator);
75+
rings[i] = MakeRing(points[i], false, memoryAllocator);
9276
}
9377

9478
return new TessellatedMultipolygon(rings);
9579
}
9680

97-
static Ring MakeRing(ReadOnlyMemory<PointF> points, RingType? ringType, MemoryAllocator allocator)
81+
static Ring MakeRing(ReadOnlyMemory<PointF> points, bool enforcePositiveOrientation, MemoryAllocator allocator)
9882
{
9983
IMemoryOwner<PointF> buffer = allocator.Allocate<PointF>(points.Length + 1);
10084
Span<PointF> span = buffer.Memory.Span;
10185
points.Span.CopyTo(span);
102-
RepeateFirstVertexAndEnsureOrientation(span, ringType);
86+
RepeateFirstVertexAndEnsureOrientation(span, enforcePositiveOrientation);
10387
return new Ring(buffer);
10488
}
10589

106-
static void RepeateFirstVertexAndEnsureOrientation(Span<PointF> span, RingType? ringType)
90+
static void RepeateFirstVertexAndEnsureOrientation(Span<PointF> span, bool enforcePositiveOrientation)
10791
{
10892
// Repeat first vertex for perf:
10993
span[span.Length - 1] = span[0];
11094

111-
if (ringType.HasValue)
95+
if (enforcePositiveOrientation)
11296
{
113-
int orientation = ringType.Value == RingType.Contour ? 1 : -1;
114-
TopologyUtilities.EnsureOrientation(span, orientation);
97+
TopologyUtilities.EnsureOrientation(span, 1);
11598
}
11699
}
117100
}
@@ -158,4 +141,4 @@ public void Dispose()
158141
}
159142
}
160143
}
161-
}
144+
}

0 commit comments

Comments
 (0)