Skip to content

Commit 05d1d10

Browse files
committed
Address PR feedback: localize error message, simplify enum, expand tests
1 parent d0c4e1d commit 05d1d10

File tree

3 files changed

+47
-5
lines changed

3 files changed

+47
-5
lines changed

src/System.Drawing.Common/src/Resources/Strings.resx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,4 +425,7 @@
425425
<data name="IconCouldNotBeExtracted" xml:space="preserve">
426426
<value>The file path could not be opened or did not contain valid data.</value>
427427
</data>
428+
<data name="ArgumentException_GdiPlus_AntiAlias24bppRgbBounds" xml:space="preserve">
429+
<value>Drawing operation exceeds the bounds of the image. This is a known GDI+ limitation with AntiAlias smoothing mode and Format24bppRgb pixel format.</value>
430+
</data>
428431
</root>

src/System.Drawing.Common/src/System/Drawing/Graphics.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,11 +1225,11 @@ public void FillRectangle(Brush brush, float x, float y, float width, float heig
12251225
// GDI+ has a bug where it writes out of bounds when using AntiAlias smoothing mode
12261226
// on a 24bppRgb bitmap, causing an AccessViolationException (or ExecutionEngineException in .NET 9+).
12271227
// We validate the parameters here to prevent the crash.
1228-
if (SmoothingMode == System.Drawing.Drawing2D.SmoothingMode.AntiAlias &&
1228+
if (SmoothingMode == Drawing2D.SmoothingMode.AntiAlias &&
12291229
_backingImage is { PixelFormat: PixelFormat.Format24bppRgb } &&
12301230
(x < 0 || y < 0 || x + width > _backingImage.Width || y + height > _backingImage.Height))
12311231
{
1232-
throw new ArgumentException("Drawing operation exceeds the bounds of the image. This is a known GDI+ limitation with AntiAlias smoothing mode and Format24bppRgb pixel format.");
1232+
throw new ArgumentException(SR.ArgumentException_GdiPlus_AntiAlias24bppRgbBounds);
12331233
}
12341234

12351235
CheckErrorStatus(PInvokeGdiPlus.GdipFillRectangle(

src/System.Drawing.Common/tests/System/Drawing/GraphicsTests.cs

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3003,8 +3003,13 @@ public void Graphics_FillRoundedRectangle_Float()
30033003
VerifyBitmapNotEmpty(bitmap);
30043004
}
30053005

3006-
[Fact]
3007-
public void FillRectangle_AntiAlias_24bppRgb_OutOfBounds_ThrowsArgumentException()
3006+
[Theory]
3007+
[InlineData(190.5f, 180.5f, 100, 100)] // Out of bounds (bottom-right)
3008+
[InlineData(-10, 10, 100, 100)] // Out of bounds (left)
3009+
[InlineData(10, -10, 100, 100)] // Out of bounds (top)
3010+
[InlineData(200, 10, 100, 100)] // Out of bounds (right)
3011+
[InlineData(10, 200, 100, 100)] // Out of bounds (bottom)
3012+
public void FillRectangle_AntiAlias_24bppRgb_OutOfBounds_ThrowsArgumentException(float x, float y, float width, float height)
30083013
{
30093014
using Bitmap bmp = new(256, 256, PixelFormat.Format24bppRgb);
30103015
using Graphics graphics = Graphics.FromImage(bmp);
@@ -3014,7 +3019,41 @@ public void FillRectangle_AntiAlias_24bppRgb_OutOfBounds_ThrowsArgumentException
30143019
// and AccessViolationException on .NET 8.
30153020
// We expect our fix to throw ArgumentException instead.
30163021
Assert.Throws<ArgumentException>(() =>
3017-
graphics.FillRectangle(Brushes.Green, new RectangleF(190.5f, 180.5f, 100, 100)));
3022+
graphics.FillRectangle(Brushes.Green, new RectangleF(x, y, width, height)));
3023+
}
3024+
3025+
[Theory]
3026+
[InlineData(0, 0, 100, 100)] // Within bounds
3027+
[InlineData(156, 156, 100, 100)] // Exactly on bounds (256 - 100 = 156)
3028+
public void FillRectangle_AntiAlias_24bppRgb_WithinBounds_Success(float x, float y, float width, float height)
3029+
{
3030+
using Bitmap bmp = new(256, 256, PixelFormat.Format24bppRgb);
3031+
using Graphics graphics = Graphics.FromImage(bmp);
3032+
graphics.SmoothingMode = SmoothingMode.AntiAlias;
3033+
3034+
graphics.FillRectangle(Brushes.Green, new RectangleF(x, y, width, height));
3035+
}
3036+
3037+
[Fact]
3038+
public void FillRectangle_DefaultSmoothing_24bppRgb_OutOfBounds_Success()
3039+
{
3040+
using Bitmap bmp = new(256, 256, PixelFormat.Format24bppRgb);
3041+
using Graphics graphics = Graphics.FromImage(bmp);
3042+
// Default SmoothingMode is None (or Invalid/Default which maps to None behavior for this check)
3043+
3044+
// Should not throw
3045+
graphics.FillRectangle(Brushes.Green, new RectangleF(190.5f, 180.5f, 100, 100));
3046+
}
3047+
3048+
[Fact]
3049+
public void FillRectangle_AntiAlias_32bppArgb_OutOfBounds_Success()
3050+
{
3051+
using Bitmap bmp = new(256, 256, PixelFormat.Format32bppArgb);
3052+
using Graphics graphics = Graphics.FromImage(bmp);
3053+
graphics.SmoothingMode = SmoothingMode.AntiAlias;
3054+
3055+
// Should not throw
3056+
graphics.FillRectangle(Brushes.Green, new RectangleF(190.5f, 180.5f, 100, 100));
30183057
}
30193058
#endif
30203059
}

0 commit comments

Comments
 (0)