Skip to content

Commit fca77ba

Browse files
Add no AA rectangle tests
1 parent dc538ad commit fca77ba

1 file changed

Lines changed: 121 additions & 0 deletions

File tree

tests/ImageSharp.Drawing.Tests/Processing/DrawingCanvasTests.Primitives.cs

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,127 @@ namespace SixLabors.ImageSharp.Drawing.Tests.Processing;
88

99
public partial class DrawingCanvasTests
1010
{
11+
[Theory]
12+
[WithBlankImage(50, 50, PixelTypes.Rgba32)]
13+
public void FillRectangle_AliasedRendersFullCorners<TPixel>(TestImageProvider<TPixel> provider)
14+
where TPixel : unmanaged, IPixel<TPixel>
15+
{
16+
const int x = 10;
17+
const int y = 10;
18+
const int w = 30;
19+
const int h = 20;
20+
21+
DrawingOptions options = new()
22+
{
23+
GraphicsOptions = new GraphicsOptions { Antialias = false }
24+
};
25+
26+
using Image<TPixel> target = provider.GetImage();
27+
using DrawingCanvas<TPixel> canvas = CreateCanvas(provider, target, options);
28+
29+
canvas.Clear(Brushes.Solid(Color.Black));
30+
canvas.Fill(Brushes.Solid(Color.White), new Rectangle(x, y, w, h));
31+
canvas.Flush();
32+
33+
target.DebugSave(provider, appendSourceFileOrDescription: false);
34+
35+
// Verify all four corner pixels are fully white.
36+
Rgba32 topLeft = target[x, y].ToRgba32();
37+
Rgba32 topRight = target[x + w - 1, y].ToRgba32();
38+
Rgba32 bottomLeft = target[x, y + h - 1].ToRgba32();
39+
Rgba32 bottomRight = target[x + w - 1, y + h - 1].ToRgba32();
40+
41+
Assert.Equal(255, topLeft.R);
42+
Assert.Equal(255, topRight.R);
43+
Assert.Equal(255, bottomLeft.R);
44+
Assert.Equal(255, bottomRight.R);
45+
46+
// Verify pixels just outside each corner are still black.
47+
Assert.Equal(0, target[x - 1, y].ToRgba32().R);
48+
Assert.Equal(0, target[x, y - 1].ToRgba32().R);
49+
Assert.Equal(0, target[x + w, y].ToRgba32().R);
50+
Assert.Equal(0, target[x + w - 1, y - 1].ToRgba32().R);
51+
Assert.Equal(0, target[x - 1, y + h - 1].ToRgba32().R);
52+
Assert.Equal(0, target[x, y + h].ToRgba32().R);
53+
Assert.Equal(0, target[x + w, y + h - 1].ToRgba32().R);
54+
Assert.Equal(0, target[x + w - 1, y + h].ToRgba32().R);
55+
56+
// Verify interior pixel count matches expected area.
57+
int whiteCount = 0;
58+
target.ProcessPixelRows(accessor =>
59+
{
60+
for (int row = 0; row < accessor.Height; row++)
61+
{
62+
Span<TPixel> span = accessor.GetRowSpan(row);
63+
for (int col = 0; col < span.Length; col++)
64+
{
65+
if (span[col].ToRgba32().R == 255)
66+
{
67+
whiteCount++;
68+
}
69+
}
70+
}
71+
});
72+
73+
Assert.Equal(w * h, whiteCount);
74+
}
75+
76+
[Theory]
77+
[WithBlankImage(50, 50, PixelTypes.Rgba32)]
78+
public void DrawRectangle_AliasedRendersFullCorners<TPixel>(TestImageProvider<TPixel> provider)
79+
where TPixel : unmanaged, IPixel<TPixel>
80+
{
81+
// A 2px pen centered on the rectangle edge places 1px inside and 1px outside.
82+
// For a rect at (10,10) size 30x20, the outer stroke boundary is (9,9)-(40,30)
83+
// and the inner boundary is (11,11)-(38,28).
84+
// Miter join ensures corners are fully filled (bevel would cut them).
85+
const int x = 10;
86+
const int y = 10;
87+
const int w = 30;
88+
const int h = 20;
89+
const float penWidth = 2;
90+
91+
DrawingOptions options = new()
92+
{
93+
GraphicsOptions = new GraphicsOptions { Antialias = false, AntialiasThreshold = 0.01F }
94+
};
95+
96+
SolidPen pen = new(new PenOptions(Color.White, penWidth, null)
97+
{
98+
StrokeOptions = new StrokeOptions { LineJoin = LineJoin.Miter }
99+
});
100+
101+
using Image<TPixel> target = provider.GetImage();
102+
using DrawingCanvas<TPixel> canvas = CreateCanvas(provider, target, options);
103+
104+
canvas.Clear(Brushes.Solid(Color.Black));
105+
canvas.Draw(pen, new Rectangle(x, y, w, h));
106+
canvas.Flush();
107+
108+
target.DebugSave(provider, appendSourceFileOrDescription: false);
109+
110+
// Outer corners of the stroke (1px outside the rect edge).
111+
Assert.Equal(255, target[x - 1, y - 1].ToRgba32().R);
112+
Assert.Equal(255, target[x + w, y - 1].ToRgba32().R);
113+
Assert.Equal(255, target[x - 1, y + h].ToRgba32().R);
114+
Assert.Equal(255, target[x + w, y + h].ToRgba32().R);
115+
116+
// Inner corners of the stroke (1px inside the rect edge).
117+
Assert.Equal(255, target[x, y].ToRgba32().R);
118+
Assert.Equal(255, target[x + w - 1, y].ToRgba32().R);
119+
Assert.Equal(255, target[x, y + h - 1].ToRgba32().R);
120+
Assert.Equal(255, target[x + w - 1, y + h - 1].ToRgba32().R);
121+
122+
// Well outside the stroke boundary should be black.
123+
Assert.Equal(0, target[x - 3, y - 3].ToRgba32().R);
124+
Assert.Equal(0, target[x + w + 2, y - 3].ToRgba32().R);
125+
Assert.Equal(0, target[x - 3, y + h + 2].ToRgba32().R);
126+
Assert.Equal(0, target[x + w + 2, y + h + 2].ToRgba32().R);
127+
128+
// Interior of the rectangle (well inside the stroke) should be black.
129+
Assert.Equal(0, target[x + (w / 2), y + (h / 2)].ToRgba32().R);
130+
}
131+
11132
[Theory]
12133
[WithBlankImage(240, 160, PixelTypes.Rgba32)]
13134
public void DrawPrimitiveHelpers_MatchesReference<TPixel>(TestImageProvider<TPixel> provider)

0 commit comments

Comments
 (0)