Skip to content

Commit 84e2c32

Browse files
Use DrawingOptions in composition and stroke commands
1 parent 9637899 commit 84e2c32

File tree

9 files changed

+98
-431
lines changed

9 files changed

+98
-431
lines changed

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

Lines changed: 22 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,34 +36,32 @@ public readonly struct CompositionCommand
3636
{
3737
private readonly IPath? sourcePath;
3838
private readonly Brush? brush;
39-
private readonly Matrix4x4 transform;
39+
private readonly DrawingOptions? drawingOptions;
40+
private readonly GraphicsOptions? layerGraphicsOptions;
4041
private readonly IReadOnlyList<IPath>? clipPaths;
41-
private readonly ShapeOptions? shapeOptions;
4242

4343
private CompositionCommand(
4444
CompositionCommandKind kind,
4545
IPath? sourcePath,
4646
Brush? brush,
47-
GraphicsOptions graphicsOptions,
47+
DrawingOptions? drawingOptions,
48+
GraphicsOptions? layerGraphicsOptions,
4849
in RasterizerOptions rasterizerOptions,
4950
Rectangle targetBounds,
5051
Rectangle layerBounds,
5152
Point destinationOffset,
52-
Matrix4x4 transform,
53-
IReadOnlyList<IPath>? clipPaths,
54-
ShapeOptions? shapeOptions)
53+
IReadOnlyList<IPath>? clipPaths)
5554
{
5655
this.Kind = kind;
5756
this.sourcePath = sourcePath;
5857
this.brush = brush;
59-
this.GraphicsOptions = graphicsOptions;
58+
this.drawingOptions = drawingOptions;
59+
this.layerGraphicsOptions = layerGraphicsOptions;
6060
this.RasterizerOptions = rasterizerOptions;
6161
this.TargetBounds = targetBounds;
6262
this.LayerBounds = layerBounds;
6363
this.DestinationOffset = destinationOffset;
64-
this.transform = transform;
6564
this.clipPaths = clipPaths;
66-
this.shapeOptions = shapeOptions;
6765
}
6866

6967
/// <summary>
@@ -90,10 +88,15 @@ private CompositionCommand(
9088
/// </summary>
9189
public Brush Brush => this.brush ?? throw new InvalidOperationException("Layer commands do not carry a brush.");
9290

91+
/// <summary>
92+
/// Gets the drawing options carried by the command.
93+
/// </summary>
94+
public DrawingOptions DrawingOptions => this.drawingOptions ?? throw new InvalidOperationException("Layer commands do not carry drawing options.");
95+
9396
/// <summary>
9497
/// Gets graphics options used for composition or layer compositing.
9598
/// </summary>
96-
public GraphicsOptions GraphicsOptions { get; }
99+
public GraphicsOptions GraphicsOptions => this.drawingOptions?.GraphicsOptions ?? this.layerGraphicsOptions!;
97100

98101
/// <summary>
99102
/// Gets rasterizer options used to generate coverage.
@@ -113,7 +116,7 @@ private CompositionCommand(
113116
/// <summary>
114117
/// Gets the command transform.
115118
/// </summary>
116-
public Matrix4x4 Transform => this.transform;
119+
public Matrix4x4 Transform => this.drawingOptions?.Transform ?? Matrix4x4.Identity;
117120

118121
/// <summary>
119122
/// Gets the clip paths carried by the command.
@@ -123,43 +126,38 @@ private CompositionCommand(
123126
/// <summary>
124127
/// Gets the shape options carried by the command.
125128
/// </summary>
126-
public ShapeOptions ShapeOptions => this.shapeOptions ?? throw new InvalidOperationException("Layer commands do not carry shape options.");
129+
public ShapeOptions ShapeOptions => this.drawingOptions?.ShapeOptions ?? throw new InvalidOperationException("Layer commands do not carry shape options.");
127130

128131
/// <summary>
129132
/// Creates a fill-path composition command.
130133
/// </summary>
131134
/// <param name="path">Path in target-local coordinates.</param>
132135
/// <param name="brush">Brush used during composition.</param>
133-
/// <param name="graphicsOptions">Graphics options used for composition.</param>
136+
/// <param name="drawingOptions">Drawing options (graphics, shape, transform) used during composition.</param>
134137
/// <param name="rasterizerOptions">Rasterizer options used to generate coverage.</param>
135-
/// <param name="shapeOptions">Shape options for clip operations.</param>
136-
/// <param name="transform">Transform matrix supplied with the command.</param>
137138
/// <param name="targetBounds">The absolute bounds of the logical target for this command.</param>
138139
/// <param name="destinationOffset">Absolute destination offset where coverage is composited.</param>
139140
/// <param name="clipPaths">Optional clip paths supplied with the command.</param>
140141
/// <returns>The composition command.</returns>
141142
public static CompositionCommand Create(
142143
IPath path,
143144
Brush brush,
144-
GraphicsOptions graphicsOptions,
145+
DrawingOptions drawingOptions,
145146
in RasterizerOptions rasterizerOptions,
146-
ShapeOptions shapeOptions,
147-
Matrix4x4 transform,
148147
Rectangle targetBounds,
149148
Point destinationOffset = default,
150149
IReadOnlyList<IPath>? clipPaths = null)
151150
=> new(
152151
CompositionCommandKind.FillLayer,
153152
path,
154153
brush,
155-
graphicsOptions,
154+
drawingOptions,
155+
null,
156156
in rasterizerOptions,
157157
targetBounds,
158158
default,
159159
destinationOffset,
160-
transform,
161-
clipPaths,
162-
shapeOptions);
160+
clipPaths);
163161

164162
/// <summary>
165163
/// Creates a begin-layer composition command.
@@ -172,13 +170,12 @@ public static CompositionCommand CreateBeginLayer(Rectangle layerBounds, Graphic
172170
CompositionCommandKind.BeginLayer,
173171
null,
174172
null,
173+
null,
175174
graphicsOptions,
176175
default,
177176
layerBounds,
178177
layerBounds,
179178
default,
180-
Matrix4x4.Identity,
181-
null,
182179
null);
183180

184181
/// <summary>
@@ -192,12 +189,11 @@ public static CompositionCommand CreateEndLayer(Rectangle layerBounds, GraphicsO
192189
CompositionCommandKind.EndLayer,
193190
null,
194191
null,
192+
null,
195193
graphicsOptions,
196194
default,
197195
layerBounds,
198196
layerBounds,
199197
default,
200-
Matrix4x4.Identity,
201-
null,
202198
null);
203199
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,33 @@ public readonly struct StrokeLineSegmentCommand
1212
{
1313
private readonly PointF sourceStart;
1414
private readonly PointF sourceEnd;
15-
private readonly Matrix4x4 transform;
15+
private readonly DrawingOptions drawingOptions;
1616

1717
/// <summary>
1818
/// Initializes a new instance of the <see cref="StrokeLineSegmentCommand"/> struct.
1919
/// </summary>
2020
/// <param name="sourceStart">The source line start point.</param>
2121
/// <param name="sourceEnd">The source line end point.</param>
2222
/// <param name="brush">The brush used to shade the stroke.</param>
23-
/// <param name="graphicsOptions">The graphics options used during composition.</param>
23+
/// <param name="drawingOptions">The drawing options (graphics, shape, transform) used during composition.</param>
2424
/// <param name="rasterizerOptions">The rasterizer options used to generate coverage.</param>
2525
/// <param name="targetBounds">The absolute bounds of the logical target.</param>
2626
/// <param name="destinationOffset">The absolute destination offset of the command.</param>
2727
/// <param name="pen">The stroke metadata.</param>
28-
/// <param name="transform">The transform applied during preparation.</param>
2928
public StrokeLineSegmentCommand(
3029
PointF sourceStart,
3130
PointF sourceEnd,
3231
Brush brush,
33-
GraphicsOptions graphicsOptions,
32+
DrawingOptions drawingOptions,
3433
in RasterizerOptions rasterizerOptions,
3534
Rectangle targetBounds,
3635
Point destinationOffset,
37-
Pen pen,
38-
Matrix4x4 transform)
36+
Pen pen)
3937
{
4038
this.sourceStart = sourceStart;
4139
this.sourceEnd = sourceEnd;
42-
this.transform = transform;
40+
this.drawingOptions = drawingOptions;
4341
this.Brush = brush;
44-
this.GraphicsOptions = graphicsOptions;
4542
this.RasterizerOptions = rasterizerOptions;
4643
this.TargetBounds = targetBounds;
4744
this.DestinationOffset = destinationOffset;
@@ -53,10 +50,15 @@ public StrokeLineSegmentCommand(
5350
/// </summary>
5451
public Brush Brush { get; }
5552

53+
/// <summary>
54+
/// Gets the drawing options carried by the command.
55+
/// </summary>
56+
public DrawingOptions DrawingOptions => this.drawingOptions;
57+
5658
/// <summary>
5759
/// Gets the graphics options used during composition.
5860
/// </summary>
59-
public GraphicsOptions GraphicsOptions { get; }
61+
public GraphicsOptions GraphicsOptions => this.drawingOptions.GraphicsOptions;
6062

6163
/// <summary>
6264
/// Gets the rasterizer options used to generate coverage.
@@ -91,7 +93,7 @@ public StrokeLineSegmentCommand(
9193
/// <summary>
9294
/// Gets the command transform.
9395
/// </summary>
94-
public Matrix4x4 Transform => this.transform;
96+
public Matrix4x4 Transform => this.drawingOptions.Transform;
9597

9698
/// <summary>
9799
/// Computes the conservative stroked bounds of one two-point line segment.

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,41 +11,34 @@ namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
1111
public readonly struct StrokePathCommand
1212
{
1313
private readonly IPath sourcePath;
14-
private readonly Matrix4x4 transform;
14+
private readonly DrawingOptions drawingOptions;
1515
private readonly IReadOnlyList<IPath>? clipPaths;
16-
private readonly ShapeOptions shapeOptions;
1716

1817
/// <summary>
1918
/// Initializes a new instance of the <see cref="StrokePathCommand"/> struct.
2019
/// </summary>
2120
/// <param name="sourcePath">The source stroke path.</param>
2221
/// <param name="brush">The brush used to shade the stroke.</param>
23-
/// <param name="graphicsOptions">The graphics options used during composition.</param>
22+
/// <param name="drawingOptions">The drawing options (graphics, shape, transform) used during composition.</param>
2423
/// <param name="rasterizerOptions">The rasterizer options used to generate coverage.</param>
25-
/// <param name="shapeOptions">The shape options used for clipping.</param>
26-
/// <param name="transform">The drawing transform applied after stroke expansion.</param>
2724
/// <param name="targetBounds">The absolute bounds of the logical target.</param>
2825
/// <param name="destinationOffset">The absolute destination offset of the command.</param>
2926
/// <param name="pen">The stroke metadata.</param>
3027
/// <param name="clipPaths">Optional clip paths supplied with the command.</param>
3128
public StrokePathCommand(
3229
IPath sourcePath,
3330
Brush brush,
34-
GraphicsOptions graphicsOptions,
31+
DrawingOptions drawingOptions,
3532
in RasterizerOptions rasterizerOptions,
36-
ShapeOptions shapeOptions,
37-
Matrix4x4 transform,
3833
Rectangle targetBounds,
3934
Point destinationOffset,
4035
Pen pen,
4136
IReadOnlyList<IPath>? clipPaths = null)
4237
{
4338
this.sourcePath = sourcePath;
44-
this.shapeOptions = shapeOptions;
45-
this.transform = transform;
39+
this.drawingOptions = drawingOptions;
4640
this.clipPaths = clipPaths;
4741
this.Brush = brush;
48-
this.GraphicsOptions = graphicsOptions;
4942
this.RasterizerOptions = rasterizerOptions;
5043
this.TargetBounds = targetBounds;
5144
this.DestinationOffset = destinationOffset;
@@ -57,10 +50,15 @@ public StrokePathCommand(
5750
/// </summary>
5851
public Brush Brush { get; }
5952

53+
/// <summary>
54+
/// Gets the drawing options carried by the command.
55+
/// </summary>
56+
public DrawingOptions DrawingOptions => this.drawingOptions;
57+
6058
/// <summary>
6159
/// Gets the graphics options used during composition.
6260
/// </summary>
63-
public GraphicsOptions GraphicsOptions { get; }
61+
public GraphicsOptions GraphicsOptions => this.drawingOptions.GraphicsOptions;
6462

6563
/// <summary>
6664
/// Gets the rasterizer options used to generate coverage.
@@ -90,7 +88,7 @@ public StrokePathCommand(
9088
/// <summary>
9189
/// Gets the drawing transform.
9290
/// </summary>
93-
public Matrix4x4 Transform => this.transform;
91+
public Matrix4x4 Transform => this.drawingOptions.Transform;
9492

9593
/// <summary>
9694
/// Gets the optional clip paths carried by the command.
@@ -100,5 +98,5 @@ public StrokePathCommand(
10098
/// <summary>
10199
/// Gets the shape options carried by the command.
102100
/// </summary>
103-
public ShapeOptions ShapeOptions => this.shapeOptions;
101+
public ShapeOptions ShapeOptions => this.drawingOptions.ShapeOptions;
104102
}

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,26 @@ namespace SixLabors.ImageSharp.Drawing.Processing.Backends;
1111
public readonly struct StrokePolylineCommand
1212
{
1313
private readonly PointF[] sourcePoints;
14-
private readonly Matrix4x4 transform;
14+
private readonly DrawingOptions drawingOptions;
1515

1616
/// <summary>
1717
/// Initializes a new instance of the <see cref="StrokePolylineCommand"/> struct.
1818
/// </summary>
1919
/// <param name="sourcePoints">The source polyline points.</param>
2020
/// <param name="brush">The brush used to shade the stroke.</param>
21-
/// <param name="graphicsOptions">The graphics options used during composition.</param>
21+
/// <param name="drawingOptions">The drawing options (graphics, shape, transform) used during composition.</param>
2222
/// <param name="rasterizerOptions">The rasterizer options used to generate coverage.</param>
2323
/// <param name="targetBounds">The absolute bounds of the logical target.</param>
2424
/// <param name="destinationOffset">The absolute destination offset of the command.</param>
2525
/// <param name="pen">The stroke metadata.</param>
26-
/// <param name="transform">The transform applied during preparation.</param>
2726
public StrokePolylineCommand(
2827
PointF[] sourcePoints,
2928
Brush brush,
30-
GraphicsOptions graphicsOptions,
29+
DrawingOptions drawingOptions,
3130
in RasterizerOptions rasterizerOptions,
3231
Rectangle targetBounds,
3332
Point destinationOffset,
34-
Pen pen,
35-
Matrix4x4 transform)
33+
Pen pen)
3634
{
3735
ArgumentNullException.ThrowIfNull(sourcePoints);
3836
if (sourcePoints.Length < 2)
@@ -41,9 +39,8 @@ public StrokePolylineCommand(
4139
}
4240

4341
this.sourcePoints = sourcePoints;
44-
this.transform = transform;
42+
this.drawingOptions = drawingOptions;
4543
this.Brush = brush;
46-
this.GraphicsOptions = graphicsOptions;
4744
this.RasterizerOptions = rasterizerOptions;
4845
this.TargetBounds = targetBounds;
4946
this.DestinationOffset = destinationOffset;
@@ -55,10 +52,15 @@ public StrokePolylineCommand(
5552
/// </summary>
5653
public Brush Brush { get; }
5754

55+
/// <summary>
56+
/// Gets the drawing options carried by the command.
57+
/// </summary>
58+
public DrawingOptions DrawingOptions => this.drawingOptions;
59+
5860
/// <summary>
5961
/// Gets the graphics options used during composition.
6062
/// </summary>
61-
public GraphicsOptions GraphicsOptions { get; }
63+
public GraphicsOptions GraphicsOptions => this.drawingOptions.GraphicsOptions;
6264

6365
/// <summary>
6466
/// Gets the rasterizer options used to generate coverage.
@@ -88,7 +90,7 @@ public StrokePolylineCommand(
8890
/// <summary>
8991
/// Gets the command transform.
9092
/// </summary>
91-
public Matrix4x4 Transform => this.transform;
93+
public Matrix4x4 Transform => this.drawingOptions.Transform;
9294

9395
/// <summary>
9496
/// Computes the conservative stroked bounds of one open polyline.

0 commit comments

Comments
 (0)