Skip to content

Commit b1247ae

Browse files
Fix nullability for brushes and rich text rendering
1 parent de47366 commit b1247ae

File tree

13 files changed

+39
-46
lines changed

13 files changed

+39
-46
lines changed

src/ImageSharp.Drawing/Processing/Extensions/DrawTextExtensions.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
#nullable disable
5-
64
using SixLabors.Fonts;
75
using SixLabors.ImageSharp.Drawing.Processing.Processors.Text;
86

@@ -163,8 +161,8 @@ public static IImageProcessingContext DrawText(
163161
this IImageProcessingContext source,
164162
RichTextOptions textOptions,
165163
string text,
166-
Brush brush,
167-
Pen pen) =>
164+
Brush? brush,
165+
Pen? pen) =>
168166
source.DrawText(source.GetDrawingOptions(), textOptions, text, brush, pen);
169167

170168
/// <summary>
@@ -221,8 +219,8 @@ public static IImageProcessingContext DrawText(
221219
DrawingOptions drawingOptions,
222220
string text,
223221
Font font,
224-
Brush brush,
225-
Pen pen,
222+
Brush? brush,
223+
Pen? pen,
226224
PointF location)
227225
{
228226
RichTextOptions textOptions = new(font) { Origin = location };
@@ -244,7 +242,7 @@ public static IImageProcessingContext DrawText(
244242
DrawingOptions drawingOptions,
245243
RichTextOptions textOptions,
246244
string text,
247-
Brush brush,
248-
Pen pen)
245+
Brush? brush,
246+
Pen? pen)
249247
=> source.ApplyProcessor(new DrawTextProcessor(drawingOptions, textOptions, text, brush, pen));
250248
}

src/ImageSharp.Drawing/Processing/GradientBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ protected GradientBrush(GradientRepetitionMode repetitionMode, params ColorStop[
3232
protected ColorStop[] ColorStops { get; }
3333

3434
/// <inheritdoc />
35-
public override bool Equals(Brush other)
35+
public override bool Equals(Brush? other)
3636
{
3737
if (other is GradientBrush brush)
3838
{

src/ImageSharp.Drawing/Processing/LinearGradientBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public LinearGradientBrush(
3232
}
3333

3434
/// <inheritdoc/>
35-
public override bool Equals(Brush other)
35+
public override bool Equals(Brush? other)
3636
{
3737
if (other is LinearGradientBrush brush)
3838
{

src/ImageSharp.Drawing/Processing/PatternBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ internal PatternBrush(PatternBrush brush)
8484
}
8585

8686
/// <inheritdoc />
87-
public override bool Equals(Brush other)
87+
public override bool Equals(Brush? other)
8888
{
8989
if (other is PatternBrush sb)
9090
{

src/ImageSharp.Drawing/Processing/PatternPen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public PatternPen(PenOptions options)
6363
}
6464

6565
/// <inheritdoc/>
66-
public override bool Equals(Pen other)
66+
public override bool Equals(Pen? other)
6767
{
6868
if (other is PatternPen)
6969
{

src/ImageSharp.Drawing/Processing/Pen.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Drawing.Processing;
2121
/// </remarks>
2222
public abstract class Pen : IEquatable<Pen>
2323
{
24-
private readonly float[] pattern;
24+
private readonly float[]? pattern;
2525

2626
/// <summary>
2727
/// Initializes a new instance of the <see cref="Pen"/> class.

src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor.cs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
#nullable disable
5-
64
using SixLabors.ImageSharp.Processing.Processors;
75

86
namespace SixLabors.ImageSharp.Drawing.Processing.Processors.Text;
@@ -20,7 +18,7 @@ public class DrawTextProcessor : IImageProcessor
2018
/// <param name="text">The text we want to render</param>
2119
/// <param name="brush">The brush to source pixel colors from.</param>
2220
/// <param name="pen">The pen to outline text with.</param>
23-
public DrawTextProcessor(DrawingOptions drawingOptions, RichTextOptions textOptions, string text, Brush brush, Pen pen)
21+
public DrawTextProcessor(DrawingOptions drawingOptions, RichTextOptions textOptions, string text, Brush? brush, Pen? pen)
2422
{
2523
Guard.NotNull(text, nameof(text));
2624
if (brush is null && pen is null)
@@ -38,7 +36,7 @@ public DrawTextProcessor(DrawingOptions drawingOptions, RichTextOptions textOpti
3836
/// <summary>
3937
/// Gets the brush used to fill the glyphs.
4038
/// </summary>
41-
public Brush Brush { get; }
39+
public Brush? Brush { get; }
4240

4341
/// <summary>
4442
/// Gets the <see cref="Processing.DrawingOptions"/> defining blending modes and shape drawing settings.
@@ -58,7 +56,7 @@ public DrawTextProcessor(DrawingOptions drawingOptions, RichTextOptions textOpti
5856
/// <summary>
5957
/// Gets the pen used for outlining the text, if Null then we will not outline
6058
/// </summary>
61-
public Pen Pen { get; }
59+
public Pen? Pen { get; }
6260

6361
/// <summary>
6462
/// Gets the location to draw the text at.

src/ImageSharp.Drawing/Processing/Processors/Text/DrawTextProcessor{TPixel}.cs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
#nullable disable
5-
64
using System.Numerics;
75
using SixLabors.Fonts;
86
using SixLabors.ImageSharp.Memory;
@@ -17,7 +15,7 @@ namespace SixLabors.ImageSharp.Drawing.Processing.Processors.Text;
1715
internal class DrawTextProcessor<TPixel> : ImageProcessor<TPixel>
1816
where TPixel : unmanaged, IPixel<TPixel>
1917
{
20-
private RichTextGlyphRenderer textRenderer;
18+
private RichTextGlyphRenderer? textRenderer;
2119
private readonly DrawTextProcessor definition;
2220

2321
public DrawTextProcessor(Configuration configuration, DrawTextProcessor definition, Image<TPixel> source, Rectangle sourceRectangle)
@@ -101,7 +99,7 @@ void Draw(IEnumerable<DrawingOperation> operations)
10199
for (int row = firstRow; row < end; row++)
102100
{
103101
int y = startY + row;
104-
Span<float> span = buffer.DangerousGetRowSpan(row).Slice(offsetSpan);
102+
Span<float> span = buffer.DangerousGetRowSpan(row)[offsetSpan..];
105103
app.Apply(span, startX, y);
106104
}
107105
}

src/ImageSharp.Drawing/Processing/Processors/Text/RichTextGlyphRenderer.cs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
// Copyright (c) Six Labors.
22
// Licensed under the Six Labors Split License.
33

4-
#nullable disable
5-
64
using System.Numerics;
75
using System.Runtime.CompilerServices;
86
using SixLabors.Fonts;
@@ -24,15 +22,15 @@ internal sealed class RichTextGlyphRenderer : BaseGlyphBuilder, IColorGlyphRende
2422

2523
private readonly DrawingOptions drawingOptions;
2624
private readonly MemoryAllocator memoryAllocator;
27-
private readonly Pen defaultPen;
28-
private readonly Brush defaultBrush;
29-
private readonly IPathInternals path;
25+
private readonly Pen? defaultPen;
26+
private readonly Brush? defaultBrush;
27+
private readonly IPathInternals? path;
3028
private bool isDisposed;
3129

3230
private readonly Dictionary<Color, Brush> brushLookup = new();
33-
private TextRun currentTextRun;
34-
private Brush currentBrush;
35-
private Pen currentPen;
31+
private TextRun? currentTextRun;
32+
private Brush? currentBrush;
33+
private Pen? currentPen;
3634
private Color? currentColor;
3735
private TextDecorationDetails? currentUnderline;
3836
private TextDecorationDetails? currentStrikeout;
@@ -54,8 +52,8 @@ public RichTextGlyphRenderer(
5452
RichTextOptions textOptions,
5553
DrawingOptions drawingOptions,
5654
MemoryAllocator memoryAllocator,
57-
Pen pen,
58-
Brush brush)
55+
Pen? pen,
56+
Brush? brush)
5957
: base(drawingOptions.Transform)
6058
{
6159
this.drawingOptions = drawingOptions;
@@ -116,7 +114,7 @@ protected override void BeginGlyph(in FontRectangle bounds, in GlyphRendererPara
116114
// Create a cache entry for the glyph.
117115
// We need to apply the default transform to the bounds to get the correct size
118116
// for comparison with future glyphs. We can use this cached glyph anywhere in the text block.
119-
var currentBounds = RectangleF.Transform(
117+
RectangleF currentBounds = RectangleF.Transform(
120118
new RectangleF(bounds.Location, new(bounds.Width, bounds.Height)),
121119
this.drawingOptions.Transform);
122120

@@ -150,8 +148,8 @@ public void SetColor(GlyphColor color)
150148

151149
public override TextDecorations EnabledDecorations()
152150
{
153-
TextRun run = this.currentTextRun;
154-
TextDecorations decorations = run.TextDecorations;
151+
TextRun? run = this.currentTextRun;
152+
TextDecorations decorations = run?.TextDecorations ?? TextDecorations.None;
155153

156154
if (this.currentTextRun is RichTextRun drawingRun)
157155
{
@@ -199,7 +197,7 @@ public override void SetDecoration(TextDecorations textDecorations, Vector2 star
199197
return;
200198
}
201199

202-
Pen pen = null;
200+
Pen? pen = null;
203201
if (this.currentTextRun is RichTextRun drawingRun)
204202
{
205203
if (textDecorations == TextDecorations.Strikeout)
@@ -224,8 +222,9 @@ public override void SetDecoration(TextDecorations textDecorations, Vector2 star
224222
else
225223
{
226224
// Clamp the thickness to whole pixels.
225+
// Brush cannot be null if pen is null.
227226
thickness = MathF.Max(1F, MathF.Round(thickness));
228-
pen = new SolidPen(this.currentBrush ?? this.defaultBrush, thickness);
227+
pen = new SolidPen((this.currentBrush ?? this.defaultBrush)!, thickness);
229228
}
230229

231230
// Drawing is always centered around the point so we need to offset by half.
@@ -275,7 +274,7 @@ protected override void EndGlyph()
275274
renderFill = true;
276275
if (this.currentColor.HasValue)
277276
{
278-
if (this.brushLookup.TryGetValue(this.currentColor.Value, out Brush brush))
277+
if (this.brushLookup.TryGetValue(this.currentColor.Value, out Brush? brush))
279278
{
280279
this.currentBrush = brush;
281280
}
@@ -309,7 +308,7 @@ protected override void EndGlyph()
309308

310309
if (renderOutline)
311310
{
312-
path = this.currentPen.GeneratePath(path);
311+
path = this.currentPen!.GeneratePath(path);
313312
renderData.OutlineMap = this.Render(path);
314313
}
315314

@@ -361,7 +360,7 @@ protected override void EndGlyph()
361360
{
362361
RenderLocation = renderLocation,
363362
Map = renderData.FillMap,
364-
Brush = this.currentBrush,
363+
Brush = this.currentBrush!,
365364
RenderPass = RenderOrderFill
366365
});
367366
}
@@ -372,7 +371,7 @@ protected override void EndGlyph()
372371
{
373372
RenderLocation = renderLocation,
374373
Map = renderData.OutlineMap,
375-
Brush = this.currentPen?.StrokeFill ?? this.currentBrush,
374+
Brush = this.currentPen?.StrokeFill ?? this.currentBrush!,
376375
RenderPass = RenderOrderOutline
377376
});
378377
}
@@ -538,7 +537,7 @@ private Buffer2D<float> Render(IPath path)
538537
// Take the path inside the path builder, scan thing and generate a Buffer2D representing the glyph.
539538
Buffer2D<float> buffer = this.memoryAllocator.Allocate2D<float>(size.Width, size.Height, AllocationOptions.Clean);
540539

541-
var scanner = PolygonScanner.Create(
540+
PolygonScanner scanner = PolygonScanner.Create(
542541
offsetPath,
543542
0,
544543
size.Height,

src/ImageSharp.Drawing/Processing/RadialGradientBrush.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ public RadialGradientBrush(
2828
}
2929

3030
/// <inheritdoc/>
31-
public override bool Equals(Brush other)
31+
public override bool Equals(Brush? other)
3232
{
3333
if (other is RadialGradientBrush brush)
3434
{

0 commit comments

Comments
 (0)