diff --git a/src/System.Drawing.Common/System.Drawing.Common.sln b/src/System.Drawing.Common/System.Drawing.Common.sln
index fe67e93fc7d3..1ef8d5b29cd3 100644
--- a/src/System.Drawing.Common/System.Drawing.Common.sln
+++ b/src/System.Drawing.Common/System.Drawing.Common.sln
@@ -7,6 +7,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Drawing.Common.Tests
{191B3618-FECD-4ABD-9D6B-5AC90DC33621} = {191B3618-FECD-4ABD-9D6B-5AC90DC33621}
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Drawing.Common.Performance.Tests", "tests\Performance\System.Drawing.Common.Performance.Tests.csproj", "{E66FFA55-0975-4F0D-8A18-24B2687FEDEA}"
+ ProjectSection(ProjectDependencies) = postProject
+ {191B3618-FECD-4ABD-9D6B-5AC90DC33621} = {191B3618-FECD-4ABD-9D6B-5AC90DC33621}
+ EndProjectSection
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Drawing.Common", "src\System.Drawing.Common.csproj", "{191B3618-FECD-4ABD-9D6B-5AC90DC33621}"
ProjectSection(ProjectDependencies) = postProject
{D7AEA698-275D-441F-B7A7-8491D1F0EFF0} = {D7AEA698-275D-441F-B7A7-8491D1F0EFF0}
@@ -30,6 +35,10 @@ Global
{4B93E684-0630-45F4-8F63-6C7788C9892F}.Debug|Any CPU.Build.0 = netcoreapp-Debug|Any CPU
{4B93E684-0630-45F4-8F63-6C7788C9892F}.Release|Any CPU.ActiveCfg = netcoreapp-Release|Any CPU
{4B93E684-0630-45F4-8F63-6C7788C9892F}.Release|Any CPU.Build.0 = netcoreapp-Release|Any CPU
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA}.Debug|Any CPU.ActiveCfg = netstandard-Debug|Any CPU
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA}.Debug|Any CPU.Build.0 = netstandard-Debug|Any CPU
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA}.Release|Any CPU.ActiveCfg = netstandard-Release|Any CPU
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA}.Release|Any CPU.Build.0 = netstandard-Release|Any CPU
{191B3618-FECD-4ABD-9D6B-5AC90DC33621}.Debug|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Debug|Any CPU
{191B3618-FECD-4ABD-9D6B-5AC90DC33621}.Debug|Any CPU.Build.0 = netcoreapp-Windows_NT-Debug|Any CPU
{191B3618-FECD-4ABD-9D6B-5AC90DC33621}.Release|Any CPU.ActiveCfg = netcoreapp-Windows_NT-Release|Any CPU
@@ -44,6 +53,7 @@ Global
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{4B93E684-0630-45F4-8F63-6C7788C9892F} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA} = {1A2F9F4A-A032-433E-B914-ADD5992BB178}
{191B3618-FECD-4ABD-9D6B-5AC90DC33621} = {E107E9C1-E893-4E87-987E-04EF0DCEAEFD}
{D7AEA698-275D-441F-B7A7-8491D1F0EFF0} = {2E666815-2EDB-464B-9DF6-380BF4789AD4}
EndGlobalSection
diff --git a/src/System.Drawing.Common/src/System.Drawing.Common.csproj b/src/System.Drawing.Common/src/System.Drawing.Common.csproj
index 269445e1e72d..7ad224fe1c62 100644
--- a/src/System.Drawing.Common/src/System.Drawing.Common.csproj
+++ b/src/System.Drawing.Common/src/System.Drawing.Common.csproj
@@ -227,6 +227,7 @@
+
@@ -379,4 +380,4 @@
-
+
\ No newline at end of file
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs
index b819ec198cff..977bfbea2b65 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.Windows.cs
@@ -183,46 +183,36 @@ public FillMode FillMode
}
}
- private PathData _GetPathData()
+ private unsafe PathData _GetPathData()
{
- int ptSize = Marshal.SizeOf(typeof(GPPOINTF));
+ int count = PointCount;
- int numPts = PointCount;
+ PathData pathData = new PathData()
+ {
+ Types = new byte[count],
+ Points = new PointF[count]
+ };
- PathData pathData = new PathData() { Types = new byte[numPts] };
+ if (count == 0)
+ return pathData;
- IntPtr memoryPathData = Marshal.AllocHGlobal(3 * IntPtr.Size);
- IntPtr memoryPoints = Marshal.AllocHGlobal(checked(ptSize * numPts));
- try
+ fixed (byte* t = pathData.Types)
+ fixed (PointF* p = pathData.Points)
{
- GCHandle typesHandle = GCHandle.Alloc(pathData.Types, GCHandleType.Pinned);
- try
+ GpPathData data = new GpPathData
{
- IntPtr typesPtr = typesHandle.AddrOfPinnedObject();
+ Count = count,
+ Points = p,
+ Types = t
+ };
- Marshal.StructureToPtr(numPts, memoryPathData, false);
- Marshal.StructureToPtr(memoryPoints, (IntPtr)((long)memoryPathData + IntPtr.Size), false);
- Marshal.StructureToPtr(typesPtr, (IntPtr)((long)memoryPathData + 2 * IntPtr.Size), false);
-
- int status = SafeNativeMethods.Gdip.GdipGetPathData(new HandleRef(this, nativePath), memoryPathData);
-
- if (status != SafeNativeMethods.Gdip.Ok)
- {
- throw SafeNativeMethods.Gdip.StatusException(status);
- }
+ int status = SafeNativeMethods.Gdip.GdipGetPathData(new HandleRef(this, nativePath), &data);
- pathData.Points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPoints, numPts);
- }
- finally
+ if (status != SafeNativeMethods.Gdip.Ok)
{
- typesHandle.Free();
+ throw SafeNativeMethods.Gdip.StatusException(status);
}
}
- finally
- {
- Marshal.FreeHGlobal(memoryPathData);
- Marshal.FreeHGlobal(memoryPoints);
- }
return pathData;
}
@@ -1094,29 +1084,22 @@ public byte[] PathTypes
return types;
}
}
- public PointF[] PathPoints
+
+ public unsafe PointF[] PathPoints
{
get
{
- int count = PointCount;
- int size = Marshal.SizeOf(typeof(GPPOINTF));
- IntPtr buf = Marshal.AllocHGlobal(checked(count * size));
- try
+ PointF[] points = new PointF[PointCount];
+ fixed(PointF* p = points)
{
- int status = SafeNativeMethods.Gdip.GdipGetPathPoints(new HandleRef(this, nativePath), new HandleRef(null, buf), count);
+ int status = SafeNativeMethods.Gdip.GdipGetPathPoints(new HandleRef(this, nativePath), p, points.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
-
- PointF[] points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, count);
- return points;
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
}
+ return points;
}
}
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
index 2e59504744ab..b30d67afb4a7 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPathIterator.cs
@@ -3,9 +3,8 @@
// See the LICENSE file in the project root for more information.
using System.Diagnostics;
-using System.Runtime.InteropServices;
-using System.Drawing.Internal;
using System.Globalization;
+using System.Runtime.InteropServices;
namespace System.Drawing.Drawing2D
{
@@ -169,36 +168,26 @@ public unsafe int Enumerate(ref PointF[] points, ref byte[] types)
if (points.Length != types.Length)
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter);
- int resultCount = 0;
- int size = Marshal.SizeOf(typeof(GPPOINTF));
- int count = points.Length;
- byte[] typesLocal = new byte[count];
+ if (points.Length == 0)
+ return 0;
- IntPtr memoryPts = Marshal.AllocHGlobal(checked(count * size));
- try
+ fixed (PointF* p = points)
+ fixed (byte* t = types)
{
- int status = SafeNativeMethods.Gdip.GdipPathIterEnumerate(new HandleRef(this, nativeIter), out resultCount,
- memoryPts, typesLocal, count);
+ int status = SafeNativeMethods.Gdip.GdipPathIterEnumerate(
+ new HandleRef(this, nativeIter),
+ out int resultCount,
+ p,
+ t,
+ points.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
- if (resultCount < count)
- {
- SafeNativeMethods.ZeroMemory((byte*)(checked((long)memoryPts + resultCount * size)), (ulong)((count - resultCount) * size));
- }
-
- points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPts, count);
- typesLocal.CopyTo(types, 0);
- }
- finally
- {
- Marshal.FreeHGlobal(memoryPts);
+ return resultCount;
}
-
- return resultCount;
}
public unsafe int CopyData(ref PointF[] points, ref byte[] types, int startIndex, int endIndex)
@@ -206,36 +195,24 @@ public unsafe int CopyData(ref PointF[] points, ref byte[] types, int startIndex
if ((points.Length != types.Length) || (endIndex - startIndex + 1 > points.Length))
throw SafeNativeMethods.Gdip.StatusException(SafeNativeMethods.Gdip.InvalidParameter);
- int resultCount = 0;
- int size = Marshal.SizeOf(typeof(GPPOINTF));
- int count = points.Length;
- byte[] typesLocal = new byte[count];
-
- IntPtr memoryPts = Marshal.AllocHGlobal(checked(count * size));
- try
+ fixed (PointF* p = points)
+ fixed (byte* t = types)
{
- int status = SafeNativeMethods.Gdip.GdipPathIterCopyData(new HandleRef(this, nativeIter), out resultCount,
- memoryPts, typesLocal, startIndex, endIndex);
+ int status = SafeNativeMethods.Gdip.GdipPathIterCopyData(
+ new HandleRef(this, nativeIter),
+ out int resultCount,
+ p,
+ t,
+ startIndex,
+ endIndex);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
- if (resultCount < count)
- {
- SafeNativeMethods.ZeroMemory((byte*)(checked((long)memoryPts + resultCount * size)), (ulong)((count - resultCount) * size));
- }
-
- points = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(memoryPts, count);
- typesLocal.CopyTo(types, 0);
- }
- finally
- {
- Marshal.FreeHGlobal(memoryPts);
+ return resultCount;
}
-
- return resultCount;
}
// handle to native path iterator object
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs
index 4bd39c992c89..f9a26b610fa8 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/Matrix.cs
@@ -261,134 +261,81 @@ public void Invert()
throw SafeNativeMethods.Gdip.StatusException(status);
}
- public void TransformPoints(PointF[] pts)
+ public unsafe void TransformPoints(PointF[] pts)
{
if (pts == null)
- throw new ArgumentNullException("pts");
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
+ throw new ArgumentNullException(nameof(pts));
- try
+ fixed (PointF* p = pts)
{
- int status = SafeNativeMethods.Gdip.GdipTransformMatrixPoints(new HandleRef(this, nativeMatrix),
- new HandleRef(null, buf),
+ int status = SafeNativeMethods.Gdip.GdipTransformMatrixPoints(
+ new HandleRef(this, nativeMatrix),
+ p,
pts.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
-
- PointF[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, pts.Length);
-
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
}
}
- public void TransformPoints(Point[] pts)
+ public unsafe void TransformPoints(Point[] pts)
{
if (pts == null)
- throw new ArgumentNullException("pts");
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
+ throw new ArgumentNullException(nameof(pts));
- try
+ fixed (Point* p = pts)
{
- int status = SafeNativeMethods.Gdip.GdipTransformMatrixPointsI(new HandleRef(this, nativeMatrix),
- new HandleRef(null, buf),
+ int status = SafeNativeMethods.Gdip.GdipTransformMatrixPointsI(
+ new HandleRef(this, nativeMatrix),
+ p,
pts.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
-
- // must do an in-place copy because we only have a reference
- Point[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTArray(buf, pts.Length);
-
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
}
}
- public void TransformVectors(PointF[] pts)
+ public unsafe void TransformVectors(PointF[] pts)
{
if (pts == null)
- {
- throw new ArgumentNullException("pts");
- }
-
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
+ throw new ArgumentNullException(nameof(pts));
- try
+ fixed (PointF* p = pts)
{
- int status = SafeNativeMethods.Gdip.GdipVectorTransformMatrixPoints(new HandleRef(this, nativeMatrix),
- new HandleRef(null, buf),
+ int status = SafeNativeMethods.Gdip.GdipVectorTransformMatrixPoints(
+ new HandleRef(this, nativeMatrix),
+ p,
pts.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
-
- // must do an in-place copy because we only have a reference
- PointF[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, pts.Length);
-
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
}
}
public void VectorTransformPoints(Point[] pts) => TransformVectors(pts);
- public void TransformVectors(Point[] pts)
+ public unsafe void TransformVectors(Point[] pts)
{
if (pts == null)
- {
- throw new ArgumentNullException("pts");
- }
+ throw new ArgumentNullException(nameof(pts));
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
-
- try
+ fixed (Point* p = pts)
{
- int status = SafeNativeMethods.Gdip.GdipVectorTransformMatrixPointsI(new HandleRef(this, nativeMatrix),
- new HandleRef(null, buf),
+ int status = SafeNativeMethods.Gdip.GdipVectorTransformMatrixPointsI(
+ new HandleRef(this, nativeMatrix),
+ p,
pts.Length);
if (status != SafeNativeMethods.Gdip.Ok)
{
throw SafeNativeMethods.Gdip.StatusException(status);
}
-
- // must do an in-place copy because we only have a reference
- Point[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTArray(buf, pts.Length);
-
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
}
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Gdiplus.cs b/src/System.Drawing.Common/src/System/Drawing/Gdiplus.cs
index 797ee7c994a1..1d42e5a2a383 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Gdiplus.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Gdiplus.cs
@@ -2,21 +2,17 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using System.Internal;
-using System.Text;
using System.Collections;
-using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-using System.IO;
using System.Drawing.Internal;
-using System.Drawing.Imaging;
-using System.Drawing.Text;
-using System.Drawing.Drawing2D;
-using System.Threading;
-using System.Security;
-using System.Runtime.ConstrainedExecution;
+using System.Internal;
+using System.IO;
using System.Runtime.CompilerServices;
+using System.Runtime.ConstrainedExecution;
+using System.Runtime.InteropServices;
+using System.Text;
+using System.Threading;
[assembly: SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "System.Drawing.SafeNativeMethods+BITMAP.bmBits")]
[assembly: SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources", Scope = "member", Target = "System.Drawing.SafeNativeMethods+DIBSECTION.dshSection")]
@@ -325,53 +321,6 @@ internal static Exception StatusException(int status)
return new ExternalException(SR.GdiplusUnknown, E_UNEXPECTED);
}
- //----------------------------------------------------------------------------------------
- // Helper function: Convert GpPointF* memory block to PointF[]
- //----------------------------------------------------------------------------------------
- internal static PointF[] ConvertGPPOINTFArrayF(IntPtr memory, int count)
- {
- if (memory == IntPtr.Zero)
- {
- throw new ArgumentNullException(nameof(memory));
- }
-
- var points = new PointF[count];
- Type pointType = typeof(GPPOINTF);
- int size = Marshal.SizeOf(pointType);
-
- for (int index = 0; index < count; index++)
- {
- var pt = (GPPOINTF)Marshal.PtrToStructure((IntPtr)((long)memory + index * size), pointType);
- points[index] = new PointF(pt.X, pt.Y);
- }
-
- return points;
- }
-
- //----------------------------------------------------------------------------------------
- // Helper function: Convert GpPoint* memory block to Point[]
- //----------------------------------------------------------------------------------------
- internal static Point[] ConvertGPPOINTArray(IntPtr memory, int count)
- {
- if (memory == IntPtr.Zero)
- {
- throw new ArgumentNullException(nameof(memory));
- }
-
- var points = new Point[count];
- Type pointType = typeof(GPPOINT);
-
- int size = Marshal.SizeOf(pointType);
-
- for (int index = 0; index < count; index++)
- {
- var pt = (GPPOINT)Marshal.PtrToStructure((IntPtr)((long)memory + index * size), pointType);
- points[index] = new Point(pt.X, pt.Y);
- }
-
- return points;
- }
-
//----------------------------------------------------------------------------------------
// Helper function: Convert PointF[] to native memory block GpPointF*
//----------------------------------------------------------------------------------------
diff --git a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs
index 2dd8b6cdde4b..f807496e1fa6 100644
--- a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.Windows.cs
@@ -2,17 +2,16 @@
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
-using Microsoft.Win32.SafeHandles;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Internal;
using System.Drawing.Text;
using System.Runtime.InteropServices;
-using System.Text;
+using Microsoft.Win32.SafeHandles;
namespace System.Drawing
{
- internal partial class SafeNativeMethods
+ internal unsafe partial class SafeNativeMethods
{
internal partial class Gdip
{
@@ -305,9 +304,9 @@ private static void LoadFunctionPointers()
private static FunctionWrapper GdipGetPathTypes_ptr;
internal static int GdipGetPathTypes(HandleRef path, byte[] types, int count) => GdipGetPathTypes_ptr.Delegate(path, types, count);
- private delegate int GdipGetPathPoints_delegate(HandleRef path, HandleRef points, int count);
+ private delegate int GdipGetPathPoints_delegate(HandleRef path, PointF* points, int count);
private static FunctionWrapper GdipGetPathPoints_ptr;
- internal static int GdipGetPathPoints(HandleRef path, HandleRef points, int count) => GdipGetPathPoints_ptr.Delegate(path, points, count);
+ internal static int GdipGetPathPoints(HandleRef path, PointF* points, int count) => GdipGetPathPoints_ptr.Delegate(path, points, count);
private delegate int GdipGetPathFillMode_delegate(HandleRef path, out int fillmode);
private static FunctionWrapper GdipGetPathFillMode_ptr;
@@ -317,9 +316,9 @@ private static void LoadFunctionPointers()
private static FunctionWrapper GdipSetPathFillMode_ptr;
internal static int GdipSetPathFillMode(HandleRef path, int fillmode) => GdipSetPathFillMode_ptr.Delegate(path, fillmode);
- private delegate int GdipGetPathData_delegate(HandleRef path, IntPtr pathData);
+ private delegate int GdipGetPathData_delegate(HandleRef path, GpPathData* pathData);
private static FunctionWrapper GdipGetPathData_ptr;
- internal static int GdipGetPathData(HandleRef path, IntPtr pathData) => GdipGetPathData_ptr.Delegate(path, pathData);
+ internal static int GdipGetPathData(HandleRef path, GpPathData* pathData) => GdipGetPathData_ptr.Delegate(path, pathData);
private delegate int GdipStartPathFigure_delegate(HandleRef path);
private static FunctionWrapper GdipStartPathFigure_ptr;
@@ -745,13 +744,13 @@ private static void LoadFunctionPointers()
private static FunctionWrapper GdipGetDpiY_ptr;
internal static int GdipGetDpiY(HandleRef graphics, float[] dpi) => GdipGetDpiY_ptr.Delegate(graphics, dpi);
- private delegate int GdipTransformPoints_delegate(HandleRef graphics, int destSpace, int srcSpace, IntPtr points, int count);
+ private delegate int GdipTransformPoints_delegate(HandleRef graphics, int destSpace, int srcSpace, PointF* points, int count);
private static FunctionWrapper GdipTransformPoints_ptr;
- internal static int GdipTransformPoints(HandleRef graphics, int destSpace, int srcSpace, IntPtr points, int count) => GdipTransformPoints_ptr.Delegate(graphics, destSpace, srcSpace, points, count);
+ internal static int GdipTransformPoints(HandleRef graphics, int destSpace, int srcSpace, PointF* points, int count) => GdipTransformPoints_ptr.Delegate(graphics, destSpace, srcSpace, points, count);
- private delegate int GdipTransformPointsI_delegate(HandleRef graphics, int destSpace, int srcSpace, IntPtr points, int count);
+ private delegate int GdipTransformPointsI_delegate(HandleRef graphics, int destSpace, int srcSpace, Point* points, int count);
private static FunctionWrapper GdipTransformPointsI_ptr;
- internal static int GdipTransformPointsI(HandleRef graphics, int destSpace, int srcSpace, IntPtr points, int count) => GdipTransformPointsI_ptr.Delegate(graphics, destSpace, srcSpace, points, count);
+ internal static int GdipTransformPointsI(HandleRef graphics, int destSpace, int srcSpace, Point* points, int count) => GdipTransformPointsI_ptr.Delegate(graphics, destSpace, srcSpace, points, count);
private delegate int GdipGetNearestColor_delegate(HandleRef graphics, ref int color);
private static FunctionWrapper GdipGetNearestColor_ptr;
@@ -769,13 +768,13 @@ private static void LoadFunctionPointers()
private static FunctionWrapper GdipDrawLineI_ptr;
internal static int GdipDrawLineI(HandleRef graphics, HandleRef pen, int x1, int y1, int x2, int y2) => GdipDrawLineI_ptr.Delegate(graphics, pen, x1, y1, x2, y2);
- private delegate int GdipDrawLines_delegate(HandleRef graphics, HandleRef pen, HandleRef points, int count);
+ private delegate int GdipDrawLines_delegate(HandleRef graphics, HandleRef pen, PointF* points, int count);
private static FunctionWrapper GdipDrawLines_ptr;
- internal static int GdipDrawLines(HandleRef graphics, HandleRef pen, HandleRef points, int count) => GdipDrawLines_ptr.Delegate(graphics, pen, points, count);
+ internal static int GdipDrawLines(HandleRef graphics, HandleRef pen, PointF* points, int count) => GdipDrawLines_ptr.Delegate(graphics, pen, points, count);
- private delegate int GdipDrawLinesI_delegate(HandleRef graphics, HandleRef pen, HandleRef points, int count);
+ private delegate int GdipDrawLinesI_delegate(HandleRef graphics, HandleRef pen, Point* points, int count);
private static FunctionWrapper GdipDrawLinesI_ptr;
- internal static int GdipDrawLinesI(HandleRef graphics, HandleRef pen, HandleRef points, int count) => GdipDrawLinesI_ptr.Delegate(graphics, pen, points, count);
+ internal static int GdipDrawLinesI(HandleRef graphics, HandleRef pen, Point* points, int count) => GdipDrawLinesI_ptr.Delegate(graphics, pen, points, count);
private delegate int GdipDrawArc_delegate(HandleRef graphics, HandleRef pen, float x, float y, float width, float height, float startAngle, float sweepAngle);
private static FunctionWrapper GdipDrawArc_ptr;
@@ -789,13 +788,13 @@ private static void LoadFunctionPointers()
private static FunctionWrapper GdipDrawBezier_ptr;
internal static int GdipDrawBezier(HandleRef graphics, HandleRef pen, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) => GdipDrawBezier_ptr.Delegate(graphics, pen, x1, y1, x2, y2, x3, y3, x4, y4);
- private delegate int GdipDrawBeziers_delegate(HandleRef graphics, HandleRef pen, HandleRef points, int count);
+ private delegate int GdipDrawBeziers_delegate(HandleRef graphics, HandleRef pen, PointF* points, int count);
private static FunctionWrapper GdipDrawBeziers_ptr;
- internal static int GdipDrawBeziers(HandleRef graphics, HandleRef pen, HandleRef points, int count) => GdipDrawBeziers_ptr.Delegate(graphics, pen, points, count);
+ internal static int GdipDrawBeziers(HandleRef graphics, HandleRef pen, PointF* points, int count) => GdipDrawBeziers_ptr.Delegate(graphics, pen, points, count);
- private delegate int GdipDrawBeziersI_delegate(HandleRef graphics, HandleRef pen, HandleRef points, int count);
+ private delegate int GdipDrawBeziersI_delegate(HandleRef graphics, HandleRef pen, Point* points, int count);
private static FunctionWrapper GdipDrawBeziersI_ptr;
- internal static int GdipDrawBeziersI(HandleRef graphics, HandleRef pen, HandleRef points, int count) => GdipDrawBeziersI_ptr.Delegate(graphics, pen, points, count);
+ internal static int GdipDrawBeziersI(HandleRef graphics, HandleRef pen, Point* points, int count) => GdipDrawBeziersI_ptr.Delegate(graphics, pen, points, count);
private delegate int GdipDrawRectangle_delegate(HandleRef graphics, HandleRef pen, float x, float y, float width, float height);
private static FunctionWrapper GdipDrawRectangle_ptr;
diff --git a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs
index b1ae6c187124..f20d0aa0b188 100644
--- a/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/GdiplusNative.cs
@@ -14,7 +14,7 @@ namespace System.Drawing
{
// Raw function imports for gdiplus
// Functions are loaded manually in order to accomodate different shared library names on Unix.
- internal partial class SafeNativeMethods
+ internal unsafe partial class SafeNativeMethods
{
internal partial class Gdip
{
@@ -509,13 +509,13 @@ private static void LoadSharedFunctionPointers()
private static FunctionWrapper GdipPathIterRewind_ptr;
internal static int GdipPathIterRewind(HandleRef pathIter) => GdipPathIterRewind_ptr.Delegate(pathIter);
- private delegate int GdipPathIterEnumerate_delegate(HandleRef pathIter, out int resultCount, IntPtr memoryPts, [In] [Out] byte[] types, int count);
+ private delegate int GdipPathIterEnumerate_delegate(HandleRef pathIter, out int resultCount, PointF* points, byte* types, int count);
private static FunctionWrapper GdipPathIterEnumerate_ptr;
- internal static int GdipPathIterEnumerate(HandleRef pathIter, out int resultCount, IntPtr memoryPts, [In] [Out] byte[] types, int count) => GdipPathIterEnumerate_ptr.Delegate(pathIter, out resultCount, memoryPts, types, count);
+ internal static int GdipPathIterEnumerate(HandleRef pathIter, out int resultCount, PointF* points, byte* types, int count) => GdipPathIterEnumerate_ptr.Delegate(pathIter, out resultCount, points, types, count);
- private delegate int GdipPathIterCopyData_delegate(HandleRef pathIter, out int resultCount, IntPtr memoryPts, [In] [Out] byte[] types, int startIndex, int endIndex);
+ private delegate int GdipPathIterCopyData_delegate(HandleRef pathIter, out int resultCount, PointF* memoryPts, byte* types, int startIndex, int endIndex);
private static FunctionWrapper GdipPathIterCopyData_ptr;
- internal static int GdipPathIterCopyData(HandleRef pathIter, out int resultCount, IntPtr memoryPts, [In] [Out] byte[] types, int startIndex, int endIndex) => GdipPathIterCopyData_ptr.Delegate(pathIter, out resultCount, memoryPts, types, startIndex, endIndex);
+ internal static int GdipPathIterCopyData(HandleRef pathIter, out int resultCount, PointF* points, byte* types, int startIndex, int endIndex) => GdipPathIterCopyData_ptr.Delegate(pathIter, out resultCount, points, types, startIndex, endIndex);
private delegate int GdipCreateHatchBrush_delegate(int hatchstyle, int forecol, int backcol, out IntPtr brush);
private static FunctionWrapper GdipCreateHatchBrush_ptr;
@@ -1259,21 +1259,21 @@ internal static unsafe int GdipGetFamilyName(HandleRef family, StringBuilder nam
private static FunctionWrapper GdipInvertMatrix_ptr;
internal static int GdipInvertMatrix(HandleRef matrix) => GdipInvertMatrix_ptr.Delegate(matrix);
- private delegate int GdipTransformMatrixPoints_delegate(HandleRef matrix, HandleRef pts, int count);
+ private delegate int GdipTransformMatrixPoints_delegate(HandleRef matrix, PointF* pts, int count);
private static FunctionWrapper GdipTransformMatrixPoints_ptr;
- internal static int GdipTransformMatrixPoints(HandleRef matrix, HandleRef pts, int count) => GdipTransformMatrixPoints_ptr.Delegate(matrix, pts, count);
+ internal static int GdipTransformMatrixPoints(HandleRef matrix, PointF* pts, int count) => GdipTransformMatrixPoints_ptr.Delegate(matrix, pts, count);
- private delegate int GdipTransformMatrixPointsI_delegate(HandleRef matrix, HandleRef pts, int count);
+ private delegate int GdipTransformMatrixPointsI_delegate(HandleRef matrix, Point* pts, int count);
private static FunctionWrapper GdipTransformMatrixPointsI_ptr;
- internal static int GdipTransformMatrixPointsI(HandleRef matrix, HandleRef pts, int count) => GdipTransformMatrixPointsI_ptr.Delegate(matrix, pts, count);
+ internal static int GdipTransformMatrixPointsI(HandleRef matrix, Point* pts, int count) => GdipTransformMatrixPointsI_ptr.Delegate(matrix, pts, count);
- private delegate int GdipVectorTransformMatrixPoints_delegate(HandleRef matrix, HandleRef pts, int count);
+ private delegate int GdipVectorTransformMatrixPoints_delegate(HandleRef matrix, PointF* pts, int count);
private static FunctionWrapper GdipVectorTransformMatrixPoints_ptr;
- internal static int GdipVectorTransformMatrixPoints(HandleRef matrix, HandleRef pts, int count) => GdipVectorTransformMatrixPoints_ptr.Delegate(matrix, pts, count);
+ internal static int GdipVectorTransformMatrixPoints(HandleRef matrix, PointF* pts, int count) => GdipVectorTransformMatrixPoints_ptr.Delegate(matrix, pts, count);
- private delegate int GdipVectorTransformMatrixPointsI_delegate(HandleRef matrix, HandleRef pts, int count);
+ private delegate int GdipVectorTransformMatrixPointsI_delegate(HandleRef matrix, Point* pts, int count);
private static FunctionWrapper GdipVectorTransformMatrixPointsI_ptr;
- internal static int GdipVectorTransformMatrixPointsI(HandleRef matrix, HandleRef pts, int count) => GdipVectorTransformMatrixPointsI_ptr.Delegate(matrix, pts, count);
+ internal static int GdipVectorTransformMatrixPointsI(HandleRef matrix, Point* pts, int count) => GdipVectorTransformMatrixPointsI_ptr.Delegate(matrix, pts, count);
private delegate int GdipGetMatrixElements_delegate(HandleRef matrix, IntPtr m);
private static FunctionWrapper GdipGetMatrixElements_ptr;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs b/src/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs
index c2c3637228e3..cedb5f5d4b42 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Graphics.Windows.cs
@@ -583,57 +583,40 @@ public void CopyFromScreen(int sourceX, int sourceY, int destinationX, int desti
}
}
- public void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] pts)
+ public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, PointF[] pts)
{
if (pts == null)
{
throw new ArgumentNullException(nameof(pts));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
- try
- {
- int status = SafeNativeMethods.Gdip.GdipTransformPoints(new HandleRef(this, NativeGraphics), unchecked((int)destSpace),
- unchecked((int)srcSpace), buf, pts.Length);
- SafeNativeMethods.Gdip.CheckStatus(status);
-
- // must do an in-place copy because we only have a reference
- PointF[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTFArrayF(buf, pts.Length);
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
+ fixed (PointF* p = pts)
{
- Marshal.FreeHGlobal(buf);
+ SafeNativeMethods.Gdip.CheckStatus(SafeNativeMethods.Gdip.GdipTransformPoints(
+ new HandleRef(this, NativeGraphics),
+ (int)destSpace,
+ (int)srcSpace,
+ p,
+ pts.Length));
}
}
[SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly")]
- public void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] pts)
+ public unsafe void TransformPoints(CoordinateSpace destSpace, CoordinateSpace srcSpace, Point[] pts)
{
if (pts == null)
{
throw new ArgumentNullException(nameof(pts));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(pts);
- try
- {
- int status = SafeNativeMethods.Gdip.GdipTransformPointsI(new HandleRef(this, NativeGraphics), unchecked((int)destSpace),
- unchecked((int)srcSpace), buf, pts.Length);
- SafeNativeMethods.Gdip.CheckStatus(status);
-
- Point[] newPts = SafeNativeMethods.Gdip.ConvertGPPOINTArray(buf, pts.Length);
- for (int i = 0; i < pts.Length; i++)
- {
- pts[i] = newPts[i];
- }
- }
- finally
+ fixed (Point* p = pts)
{
- Marshal.FreeHGlobal(buf);
+ SafeNativeMethods.Gdip.CheckStatus(SafeNativeMethods.Gdip.GdipTransformPointsI(
+ new HandleRef(this, NativeGraphics),
+ (int)destSpace,
+ (int)srcSpace,
+ p,
+ pts.Length));
}
}
@@ -671,7 +654,7 @@ public void DrawLine(Pen pen, PointF pt1, PointF pt2)
///
/// Draws a series of line segments that connect an array of points.
///
- public void DrawLines(Pen pen, PointF[] points)
+ public unsafe void DrawLines(Pen pen, PointF[] points)
{
if (pen == null)
{
@@ -683,16 +666,12 @@ public void DrawLines(Pen pen, PointF[] points)
throw new ArgumentNullException(nameof(points));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
- try
- {
- int status = SafeNativeMethods.Gdip.GdipDrawLines(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen),
- new HandleRef(this, buf), points.Length);
- CheckErrorStatus(status);
- }
- finally
+ fixed (PointF* p = points)
{
- Marshal.FreeHGlobal(buf);
+ CheckErrorStatus(SafeNativeMethods.Gdip.GdipDrawLines(
+ new HandleRef(this, NativeGraphics),
+ new HandleRef(pen, pen.NativePen),
+ p, points.Length));
}
}
@@ -722,7 +701,7 @@ public void DrawLine(Pen pen, Point pt1, Point pt2)
///
/// Draws a series of line segments that connect an array of points.
///
- public void DrawLines(Pen pen, Point[] points)
+ public unsafe void DrawLines(Pen pen, Point[] points)
{
if (pen == null)
{
@@ -734,16 +713,13 @@ public void DrawLines(Pen pen, Point[] points)
throw new ArgumentNullException(nameof(points));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
- try
- {
- int status = SafeNativeMethods.Gdip.GdipDrawLinesI(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen),
- new HandleRef(this, buf), points.Length);
- CheckErrorStatus(status);
- }
- finally
+ fixed (Point* p = points)
{
- Marshal.FreeHGlobal(buf);
+ CheckErrorStatus(SafeNativeMethods.Gdip.GdipDrawLinesI(
+ new HandleRef(this, NativeGraphics),
+ new HandleRef(pen, pen.NativePen),
+ p,
+ points.Length));
}
}
@@ -824,7 +800,7 @@ public void DrawBezier(Pen pen, PointF pt1, PointF pt2, PointF pt3, PointF pt4)
///
/// Draws a series of cubic Bezier curves from an array of points.
///
- public void DrawBeziers(Pen pen, PointF[] points)
+ public unsafe void DrawBeziers(Pen pen, PointF[] points)
{
if (pen == null)
{
@@ -836,16 +812,12 @@ public void DrawBeziers(Pen pen, PointF[] points)
throw new ArgumentNullException(nameof(points));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
- try
- {
- int status = SafeNativeMethods.Gdip.GdipDrawBeziers(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen),
- new HandleRef(this, buf), points.Length);
- CheckErrorStatus(status);
- }
- finally
+ fixed (PointF* p = points)
{
- Marshal.FreeHGlobal(buf);
+ CheckErrorStatus(SafeNativeMethods.Gdip.GdipDrawBeziers(
+ new HandleRef(this, NativeGraphics),
+ new HandleRef(pen, pen.NativePen),
+ p, points.Length));
}
}
@@ -860,7 +832,7 @@ public void DrawBezier(Pen pen, Point pt1, Point pt2, Point pt3, Point pt4)
///
/// Draws a series of cubic Bezier curves from an array of points.
///
- public void DrawBeziers(Pen pen, Point[] points)
+ public unsafe void DrawBeziers(Pen pen, Point[] points)
{
if (pen == null)
{
@@ -872,16 +844,13 @@ public void DrawBeziers(Pen pen, Point[] points)
throw new ArgumentNullException(nameof(points));
}
- IntPtr buf = SafeNativeMethods.Gdip.ConvertPointToMemory(points);
- try
+ fixed (Point* p = points)
{
- int status = SafeNativeMethods.Gdip.GdipDrawBeziersI(new HandleRef(this, NativeGraphics), new HandleRef(pen, pen.NativePen),
- new HandleRef(this, buf), points.Length);
- CheckErrorStatus(status);
- }
- finally
- {
- Marshal.FreeHGlobal(buf);
+ CheckErrorStatus(SafeNativeMethods.Gdip.GdipDrawBeziersI(
+ new HandleRef(this, NativeGraphics),
+ new HandleRef(pen, pen.NativePen),
+ p,
+ points.Length));
}
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Internal/GpPathData.cs b/src/System.Drawing.Common/src/System/Drawing/Internal/GpPathData.cs
new file mode 100644
index 000000000000..ce97b0a42677
--- /dev/null
+++ b/src/System.Drawing.Common/src/System/Drawing/Internal/GpPathData.cs
@@ -0,0 +1,16 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Runtime.InteropServices;
+
+namespace System.Drawing.Internal
+{
+ [StructLayout(LayoutKind.Sequential)]
+ internal unsafe struct GpPathData
+ {
+ public int Count;
+ public PointF* Points;
+ public byte* Types;
+ }
+}
diff --git a/src/System.Drawing.Common/tests/DrawingTest.cs b/src/System.Drawing.Common/tests/DrawingTest.cs
new file mode 100644
index 000000000000..f5496970691a
--- /dev/null
+++ b/src/System.Drawing.Common/tests/DrawingTest.cs
@@ -0,0 +1,25 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using System.Drawing.Imaging;
+using System.IO;
+using Xunit;
+
+namespace System.Drawing.Tests
+{
+ public abstract class DrawingTest
+ {
+ private static Security.Cryptography.MD5 s_md5 = Security.Cryptography.MD5.Create();
+
+ protected void ValidateImageContent(Image image, byte[] expectedHash)
+ {
+ using (MemoryStream stream = new MemoryStream(4096))
+ {
+ image.Save(stream, ImageFormat.Bmp);
+ stream.Seek(0, SeekOrigin.Begin);
+ byte[] hash = s_md5.ComputeHash(stream);
+ Assert.Equal(expectedHash, hash);
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/GraphicsTests.cs b/src/System.Drawing.Common/tests/GraphicsTests.cs
index dec60407bb80..e6afbbaa5019 100644
--- a/src/System.Drawing.Common/tests/GraphicsTests.cs
+++ b/src/System.Drawing.Common/tests/GraphicsTests.cs
@@ -2,13 +2,10 @@
// See the LICENSE file in the project root for more information.
using System.Collections.Generic;
-using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
-using System.Linq;
using Xunit;
-using Xunit.Sdk;
namespace System.Drawing.Tests
{
@@ -2290,160 +2287,6 @@ public void GetNearestColor_Disposed_ThrowsArgumentException()
}
}
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLine_NullPen_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- AssertExtensions.Throws("pen", () => graphics.DrawLine(null, Point.Empty, Point.Empty));
- AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0, 0, 0, 0));
- AssertExtensions.Throws("pen", () => graphics.DrawLine(null, PointF.Empty, PointF.Empty));
- AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0f, 0f, 0f, 0f));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLine_DisposedPen_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- var pen = new Pen(Color.Red);
- pen.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLine_Busy_ThrowsInvalidOperationException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- IntPtr hdc = graphics.GetHdc();
- try
- {
- Assert.Throws(() => graphics.DrawLine(pen, Point.Empty, Point.Empty));
- Assert.Throws(() => graphics.DrawLine(pen, 0, 0, 0, 0));
- Assert.Throws(() => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
- Assert.Throws(() => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
- }
- finally
- {
- graphics.ReleaseHdc();
- }
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLine_Disposed_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (var pen = new Pen(Color.Red))
- {
- Graphics graphics = Graphics.FromImage(image);
- graphics.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
- AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLines_NullPen_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new Point[2]));
- AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new PointF[2]));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLines_DisposedPen_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- var pen = new Pen(Color.Red);
- pen.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2]));
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2]));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLines_NullPoints_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (Point[])null));
- AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (PointF[])null));
- }
- }
-
- [ConditionalTheory(Helpers.GdiplusIsAvailable)]
- [InlineData(0)]
- [InlineData(1)]
- public void DrawLines_InvalidPointsLength_ThrowsArgumentException(int length)
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[length]));
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[length]));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLines_Busy_ThrowsInvalidOperationException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- IntPtr hdc = graphics.GetHdc();
- try
- {
- Assert.Throws(() => graphics.DrawLines(pen, new Point[2]));
- Assert.Throws(() => graphics.DrawLines(pen, new PointF[2]));
- }
- finally
- {
- graphics.ReleaseHdc();
- }
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawLines_Disposed_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (var pen = new Pen(Color.Red))
- {
- Graphics graphics = Graphics.FromImage(image);
- graphics.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2]));
- AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2]));
- }
- }
-
[ActiveIssue(20884, TestPlatforms.AnyUnix)]
[ConditionalFact(Helpers.GdiplusIsAvailable)]
public void DrawArc_NullPen_ThrowsArgumentNullException()
@@ -2545,159 +2388,6 @@ public void DrawArc_Disposed_ThrowsArgumentException()
}
}
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBezier_NullPen_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, 1, 2, 3, 4, 5, 6, 7, 8));
- AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
- AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBezier_DisposedPen_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- var pen = new Pen(Color.Red);
- pen.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8));
- AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
- AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBezier_Busy_ThrowsInvalidOperationException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- IntPtr hdc = graphics.GetHdc();
- try
- {
- Assert.Throws(() => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8));
- Assert.Throws(() => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
- Assert.Throws(() => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
- }
- finally
- {
- graphics.ReleaseHdc();
- }
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBezier_Disposed_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (var pen = new Pen(Color.Red))
- {
- Graphics graphics = Graphics.FromImage(image);
- graphics.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90));
- AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90));
- AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90));
- AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_NullPen_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new Point[2]));
- AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new PointF[2]));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_DisposedPen_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- {
- var pen = new Pen(Color.Red);
- pen.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2]));
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2]));
- }
- }
-
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_NullPoints_ThrowsArgumentNullException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (Point[])null));
- AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (PointF[])null));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_EmptyPoints_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[0]));
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[0]));
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_Busy_ThrowsInvalidOperationException()
- {
- using (var image = new Bitmap(10, 10))
- using (Graphics graphics = Graphics.FromImage(image))
- using (var pen = new Pen(Color.Red))
- {
- IntPtr hdc = graphics.GetHdc();
- try
- {
- Assert.Throws(() => graphics.DrawBeziers(pen, new Point[2]));
- Assert.Throws(() => graphics.DrawBeziers(pen, new PointF[2]));
- }
- finally
- {
- graphics.ReleaseHdc();
- }
- }
- }
-
- [ActiveIssue(20884, TestPlatforms.AnyUnix)]
- [ConditionalFact(Helpers.GdiplusIsAvailable)]
- public void DrawBeziers_Disposed_ThrowsArgumentException()
- {
- using (var image = new Bitmap(10, 10))
- using (var pen = new Pen(Color.Red))
- {
- Graphics graphics = Graphics.FromImage(image);
- graphics.Dispose();
-
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2]));
- AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2]));
- }
- }
-
[ConditionalFact(Helpers.GdiplusIsAvailable)]
public void DrawRectangle_NullPen_ThrowsArgumentNullException()
{
diff --git a/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs b/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs
new file mode 100644
index 000000000000..48d97b427c74
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Graphics_DrawBezierTests.cs
@@ -0,0 +1,220 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Drawing.Tests
+{
+ public class Graphics_DrawBezierTests : DrawingTest
+ {
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_Point()
+ {
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.White))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ graphics.DrawBezier(pen, new Point(10, 10), new Point(20, 1), new Point(35, 5), new Point(50, 10));
+ ValidateImageContent(image,
+ PlatformDetection.IsWindows
+ ? new byte[] { 0xa4, 0xb9, 0x73, 0xb9, 0x6f, 0x3a, 0x85, 0x21, 0xd3, 0x65, 0x87, 0x24, 0xcf, 0x6d, 0x61, 0x94 }
+ : new byte[] { 0xcf, 0x92, 0xaa, 0xe2, 0x44, 0xd4, 0xdd, 0xae, 0xdd, 0x4c, 0x8a, 0xf5, 0xc3, 0x65, 0xac, 0xf2 });
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_Points()
+ {
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.Red))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ Point[] points =
+ {
+ new Point(10, 10), new Point(20, 1), new Point(35, 5), new Point(50, 10),
+ new Point(60, 15), new Point(65, 25), new Point(50, 30)
+ };
+
+ graphics.DrawBeziers(pen, points);
+ ValidateImageContent(image,
+ PlatformDetection.IsWindows
+ ? new byte[] { 0xd0, 0x00, 0x08, 0x21, 0x06, 0x29, 0xd8, 0xab, 0x19, 0xc5, 0xc9, 0xf6, 0xf2, 0x69, 0x30, 0x1f }
+ : new byte[] { 0x9d, 0x24, 0x9f, 0x91, 0xa3, 0xa5, 0x60, 0xde, 0x14, 0x69, 0x42, 0xa8, 0xe6, 0xc6, 0xbf, 0xc9 });
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_PointFs()
+ {
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.Red))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ PointF[] points =
+ {
+ new PointF(10.0F, 10.0F), new PointF(20.0F, 1.0F), new PointF(35.0F, 5.0F), new PointF(50.0F, 10.0F),
+ new PointF(60.0F, 15.0F), new PointF(65.0F, 25.0F), new PointF(50.0F, 30.0F)
+ };
+
+ graphics.DrawBeziers(pen, points);
+ ValidateImageContent(image,
+ PlatformDetection.IsWindows
+ ? new byte[] { 0xd0, 0x00, 0x08, 0x21, 0x06, 0x29, 0xd8, 0xab, 0x19, 0xc5, 0xc9, 0xf6, 0xf2, 0x69, 0x30, 0x1f }
+ : new byte[] { 0x9d, 0x24, 0x9f, 0x91, 0xa3, 0xa5, 0x60, 0xde, 0x14, 0x69, 0x42, 0xa8, 0xe6, 0xc6, 0xbf, 0xc9 });
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_NullPen_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, 1, 2, 3, 4, 5, 6, 7, 8));
+ AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
+ AssertExtensions.Throws("pen", () => graphics.DrawBezier(null, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_DisposedPen_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ var pen = new Pen(Color.Red);
+ pen.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8));
+ AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
+ AssertExtensions.Throws(null, () => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_Busy_ThrowsInvalidOperationException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ IntPtr hdc = graphics.GetHdc();
+ try
+ {
+ Assert.Throws(() => graphics.DrawBezier(pen, 1, 2, 3, 4, 5, 6, 7, 8));
+ Assert.Throws(() => graphics.DrawBezier(pen, Point.Empty, Point.Empty, Point.Empty, Point.Empty));
+ Assert.Throws(() => graphics.DrawBezier(pen, PointF.Empty, PointF.Empty, PointF.Empty, PointF.Empty));
+ }
+ finally
+ {
+ graphics.ReleaseHdc();
+ }
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBezier_Disposed_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (var pen = new Pen(Color.Red))
+ {
+ Graphics graphics = Graphics.FromImage(image);
+ graphics.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new Rectangle(0, 0, 1, 1), 0, 90));
+ AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0, 0, 1, 1, 0, 90));
+ AssertExtensions.Throws(null, () => graphics.DrawArc(pen, new RectangleF(0, 0, 1, 1), 0, 90));
+ AssertExtensions.Throws(null, () => graphics.DrawArc(pen, 0f, 0f, 1f, 1f, 0, 90));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_NullPen_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new Point[2]));
+ AssertExtensions.Throws("pen", () => graphics.DrawBeziers(null, new PointF[2]));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_DisposedPen_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ var pen = new Pen(Color.Red);
+ pen.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2]));
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2]));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_NullPoints_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (Point[])null));
+ AssertExtensions.Throws("points", () => graphics.DrawBeziers(pen, (PointF[])null));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_EmptyPoints_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[0]));
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[0]));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_Busy_ThrowsInvalidOperationException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ IntPtr hdc = graphics.GetHdc();
+ try
+ {
+ Assert.Throws(() => graphics.DrawBeziers(pen, new Point[2]));
+ Assert.Throws(() => graphics.DrawBeziers(pen, new PointF[2]));
+ }
+ finally
+ {
+ graphics.ReleaseHdc();
+ }
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawBeziers_Disposed_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (var pen = new Pen(Color.Red))
+ {
+ Graphics graphics = Graphics.FromImage(image);
+ graphics.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new Point[2]));
+ AssertExtensions.Throws(null, () => graphics.DrawBeziers(pen, new PointF[2]));
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs b/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs
new file mode 100644
index 000000000000..8ee717c76d1b
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Graphics_DrawLineTests.cs
@@ -0,0 +1,195 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+
+using Xunit;
+
+namespace System.Drawing.Tests
+{
+ public class Graphics_DrawLineTests : DrawingTest
+ {
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_Points()
+ {
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.White))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ graphics.DrawLines(pen, new Point[] { new Point(1, 1), new Point(1, 10), new Point(20, 5), new Point(25, 30) });
+ ValidateImageContent(image,
+ PlatformDetection.IsWindows
+ ? new byte[] { 0x8e, 0xc2, 0xfb, 0xb4, 0xde, 0x5d, 0xdc, 0xd2, 0x31, 0xbd, 0xd3, 0x9a, 0xcf, 0xc1, 0xd4, 0xad }
+ : new byte[] { 0x55, 0x40, 0xd8, 0xaa, 0xc7, 0x36, 0x06, 0x18, 0x1a, 0x57, 0x2b, 0xa9, 0x5a, 0xff, 0x2b, 0xb2 });
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_PointFs()
+ {
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.White))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ graphics.DrawLines(pen, new PointF[] { new PointF(1.0F, 1.0F), new PointF(1.0F, 10.0F), new PointF(20.0F, 5.0F), new PointF(25.0F, 30.0F) });
+ ValidateImageContent(image,
+ PlatformDetection.IsWindows
+ ? new byte[] { 0x8e, 0xc2, 0xfb, 0xb4, 0xde, 0x5d, 0xdc, 0xd2, 0x31, 0xbd, 0xd3, 0x9a, 0xcf, 0xc1, 0xd4, 0xad }
+ : new byte[] { 0x55, 0x40, 0xd8, 0xaa, 0xc7, 0x36, 0x06, 0x18, 0x1a, 0x57, 0x2b, 0xa9, 0x5a, 0xff, 0x2b, 0xb2 });
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLine_NullPen_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ AssertExtensions.Throws("pen", () => graphics.DrawLine(null, Point.Empty, Point.Empty));
+ AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0, 0, 0, 0));
+ AssertExtensions.Throws("pen", () => graphics.DrawLine(null, PointF.Empty, PointF.Empty));
+ AssertExtensions.Throws("pen", () => graphics.DrawLine(null, 0f, 0f, 0f, 0f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLine_DisposedPen_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ var pen = new Pen(Color.Red);
+ pen.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLine_Busy_ThrowsInvalidOperationException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ IntPtr hdc = graphics.GetHdc();
+ try
+ {
+ Assert.Throws(() => graphics.DrawLine(pen, Point.Empty, Point.Empty));
+ Assert.Throws(() => graphics.DrawLine(pen, 0, 0, 0, 0));
+ Assert.Throws(() => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
+ Assert.Throws(() => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
+ }
+ finally
+ {
+ graphics.ReleaseHdc();
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLine_Disposed_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (var pen = new Pen(Color.Red))
+ {
+ Graphics graphics = Graphics.FromImage(image);
+ graphics.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, Point.Empty, Point.Empty));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0, 0, 0, 0));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, PointF.Empty, PointF.Empty));
+ AssertExtensions.Throws(null, () => graphics.DrawLine(pen, 0f, 0f, 0f, 0f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_NullPen_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new Point[2]));
+ AssertExtensions.Throws("pen", () => graphics.DrawLines(null, new PointF[2]));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_DisposedPen_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ var pen = new Pen(Color.Red);
+ pen.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2]));
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2]));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_NullPoints_ThrowsArgumentNullException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (Point[])null));
+ AssertExtensions.Throws("points", () => graphics.DrawLines(pen, (PointF[])null));
+ }
+ }
+
+ [ConditionalTheory(Helpers.GdiplusIsAvailable)]
+ [InlineData(0)]
+ [InlineData(1)]
+ public void DrawLines_InvalidPointsLength_ThrowsArgumentException(int length)
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[length]));
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[length]));
+ }
+ }
+
+ [ActiveIssue(20884, TestPlatforms.AnyUnix)]
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_Busy_ThrowsInvalidOperationException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (Graphics graphics = Graphics.FromImage(image))
+ using (var pen = new Pen(Color.Red))
+ {
+ IntPtr hdc = graphics.GetHdc();
+ try
+ {
+ Assert.Throws(() => graphics.DrawLines(pen, new Point[2]));
+ Assert.Throws(() => graphics.DrawLines(pen, new PointF[2]));
+ }
+ finally
+ {
+ graphics.ReleaseHdc();
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLines_Disposed_ThrowsArgumentException()
+ {
+ using (var image = new Bitmap(10, 10))
+ using (var pen = new Pen(Color.Red))
+ {
+ Graphics graphics = Graphics.FromImage(image);
+ graphics.Dispose();
+
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new Point[2]));
+ AssertExtensions.Throws(null, () => graphics.DrawLines(pen, new PointF[2]));
+ }
+ }
+
+ }
+}
diff --git a/src/System.Drawing.Common/tests/Performance/Configurations.props b/src/System.Drawing.Common/tests/Performance/Configurations.props
new file mode 100644
index 000000000000..78953dfc8851
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Performance/Configurations.props
@@ -0,0 +1,8 @@
+
+
+
+
+ netstandard;
+
+
+
diff --git a/src/System.Drawing.Common/tests/Performance/Perf_Graphics_DrawBeziers.cs b/src/System.Drawing.Common/tests/Performance/Perf_Graphics_DrawBeziers.cs
new file mode 100644
index 000000000000..87ef22dfbce5
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Performance/Perf_Graphics_DrawBeziers.cs
@@ -0,0 +1,61 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using Microsoft.Xunit.Performance;
+
+namespace System.Drawing.Tests
+{
+ public class Perf_Graphics_DrawBeziers : RemoteExecutorTestBase
+ {
+ [Benchmark(InnerIterationCount = 10000)]
+ public void DrawBezier_Point()
+ {
+ Random r = new Random(1942);
+
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.White))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ graphics.DrawBezier(pen, new Point(r.Next(100), r.Next(100)), new Point(r.Next(100), r.Next(100)), new Point(r.Next(100), r.Next(100)), new Point(r.Next(100), r.Next(100)));
+ }
+ }
+ }
+ }
+ }
+
+ [Benchmark(InnerIterationCount = 10000)]
+ public void DrawBezier_Points()
+ {
+ Point[] points =
+ {
+ new Point(10, 10), new Point(20, 1), new Point(35, 5), new Point(50, 10),
+ new Point(60, 15), new Point(65, 25), new Point(50, 30)
+ };
+
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Pen pen = new Pen(Color.Blue))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ graphics.DrawBeziers(pen, points);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/Performance/Perf_Graphics_Transforms.cs b/src/System.Drawing.Common/tests/Performance/Perf_Graphics_Transforms.cs
new file mode 100644
index 000000000000..bc84d484425b
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Performance/Perf_Graphics_Transforms.cs
@@ -0,0 +1,41 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+using System.Diagnostics;
+using System.Drawing.Drawing2D;
+using Microsoft.Xunit.Performance;
+
+namespace System.Drawing.Tests
+{
+ public class Perf_Graphics_Transforms : RemoteExecutorTestBase
+ {
+ [Benchmark(InnerIterationCount = 10000)]
+ public void TransformPoints()
+ {
+ Point[] points =
+ {
+ new Point(10, 10), new Point(20, 1), new Point(35, 5), new Point(50, 10),
+ new Point(60, 15), new Point(65, 25), new Point(50, 30)
+ };
+
+ using (Bitmap image = new Bitmap(100, 100))
+ using (Graphics graphics = Graphics.FromImage(image))
+ {
+ foreach (var iteration in Benchmark.Iterations)
+ {
+
+ using (iteration.StartMeasurement())
+ {
+ for (int i = 0; i < Benchmark.InnerIterationCount; i++)
+ {
+ graphics.TransformPoints(CoordinateSpace.World, CoordinateSpace.Page, points);
+ graphics.TransformPoints(CoordinateSpace.Device, CoordinateSpace.World, points);
+ graphics.TransformPoints(CoordinateSpace.Page, CoordinateSpace.Device, points);
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/Performance/System.Drawing.Common.Performance.Tests.csproj b/src/System.Drawing.Common/tests/Performance/System.Drawing.Common.Performance.Tests.csproj
new file mode 100644
index 000000000000..d36e367eeaab
--- /dev/null
+++ b/src/System.Drawing.Common/tests/Performance/System.Drawing.Common.Performance.Tests.csproj
@@ -0,0 +1,32 @@
+
+
+
+
+ InnerLoop;OuterLoop
+ true
+ {E66FFA55-0975-4F0D-8A18-24B2687FEDEA}
+
+
+
+
+
+
+
+ {69e46a6f-9966-45a5-8945-2559fe337827}
+ RemoteExecutorConsoleApp
+
+
+ Common\System\PerfUtils.cs
+
+
+
+
+ {69e46a6f-9966-45a5-8945-2559fe337827}
+ PerfRunner
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj b/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj
index cc2bf1d3a56f..982077e36e04 100644
--- a/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj
+++ b/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj
@@ -23,9 +23,12 @@
+
+
+