Skip to content

Commit 3441b89

Browse files
Fix orientation, update ref output
1 parent 586fe94 commit 3441b89

364 files changed

Lines changed: 868 additions & 2038 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/ImageSharp.Drawing/Processing/Backends/CompositionCommand.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public struct CompositionCommand
1818
private readonly Matrix4x4 transform;
1919
private readonly IReadOnlyList<IPath>? clipPaths;
2020
private readonly ShapeOptions shapeOptions;
21+
private readonly bool enforceFillOrientation;
2122

2223
private CompositionCommand(
2324
int definitionKey,
@@ -29,7 +30,8 @@ private CompositionCommand(
2930
Pen? pen,
3031
Matrix4x4 transform,
3132
IReadOnlyList<IPath>? clipPaths,
32-
ShapeOptions shapeOptions)
33+
ShapeOptions shapeOptions,
34+
bool enforceFillOrientation)
3335
{
3436
this.DefinitionKey = definitionKey;
3537
this.sourcePath = sourcePath;
@@ -42,6 +44,7 @@ private CompositionCommand(
4244
this.transform = transform;
4345
this.clipPaths = clipPaths;
4446
this.shapeOptions = shapeOptions;
47+
this.enforceFillOrientation = enforceFillOrientation;
4548
}
4649

4750
/// <summary>
@@ -92,6 +95,10 @@ private CompositionCommand(
9295
/// <param name="rasterizerOptions">Rasterizer options used to generate coverage.</param>
9396
/// <param name="shapeOptions">Shape options for clip operations.</param>
9497
/// <param name="transform">Transform matrix to apply during preparation.</param>
98+
/// <param name="enforceFillOrientation">
99+
/// When <see langword="true"/>, preparation normalizes closed contour orientation before rasterization.
100+
/// Callers should only enable this when they explicitly want contour winding rewritten.
101+
/// </param>
95102
/// <param name="destinationOffset">Absolute destination offset where coverage is composited.</param>
96103
/// <param name="pen">Optional pen for stroke commands. The batcher expands strokes to fills.</param>
97104
/// <param name="clipPaths">Optional clip paths to apply during preparation.</param>
@@ -103,6 +110,7 @@ public static CompositionCommand Create(
103110
in RasterizerOptions rasterizerOptions,
104111
ShapeOptions shapeOptions,
105112
Matrix4x4 transform,
113+
bool enforceFillOrientation,
106114
Point destinationOffset = default,
107115
Pen? pen = null,
108116
IReadOnlyList<IPath>? clipPaths = null)
@@ -119,7 +127,8 @@ public static CompositionCommand Create(
119127
pen,
120128
transform,
121129
clipPaths,
122-
shapeOptions);
130+
shapeOptions,
131+
enforceFillOrientation);
123132
}
124133

125134
/// <summary>
@@ -178,7 +187,7 @@ internal void Prepare(GeometryPreparationCache? geometryCache = null)
178187
/// </summary>
179188
/// <returns>The geometry preparation cache key.</returns>
180189
internal readonly GeometryPreparationCache.GeometryPreparationKey CreateGeometryPreparationKey()
181-
=> new(this.sourcePath, this.transform, this.pen, this.clipPaths, this.shapeOptions);
190+
=> new(this.sourcePath, this.transform, this.pen, this.clipPaths, this.shapeOptions, this.enforceFillOrientation);
182191

183192
/// <summary>
184193
/// Builds prepared geometry for this command without consulting any external cache.
@@ -207,7 +216,7 @@ internal readonly PreparedGeometry BuildPreparedGeometry()
207216
}
208217

209218
// Line preparation happens here so backends no longer need to traverse IPath.
210-
return PreparedGeometry.Create(path, enforceFillOrientation: this.pen is null);
219+
return PreparedGeometry.Create(path, enforceFillOrientation: this.enforceFillOrientation);
211220
}
212221

213222
/// <summary>

0 commit comments

Comments
 (0)