diff --git a/src/CoreFx.Private.TestUtilities/ref/CoreFx.Private.TestUtilities.cs b/src/CoreFx.Private.TestUtilities/ref/CoreFx.Private.TestUtilities.cs
index 9f9f65465c80..f858e84591a5 100644
--- a/src/CoreFx.Private.TestUtilities/ref/CoreFx.Private.TestUtilities.cs
+++ b/src/CoreFx.Private.TestUtilities/ref/CoreFx.Private.TestUtilities.cs
@@ -73,6 +73,7 @@ public static partial class PlatformDetection
public static bool IsNotRedHat { get { throw null; } }
public static bool IsRedHat69 { get { throw null; } }
public static bool IsNotRedHat69 { get { throw null; } }
+ public static bool IsRedHat73 { get { throw null; } }
public static bool IsUap { get { throw null; } }
public static Version ICUVersion { get { return null; } }
public static bool IsUbuntu { get { throw null; } }
diff --git a/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Unix.cs b/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Unix.cs
index abb86f939948..96d18911cb7c 100644
--- a/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Unix.cs
+++ b/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Unix.cs
@@ -49,6 +49,7 @@ public static partial class PlatformDetection
public static bool IsNotRedHat => !IsRedHat;
public static bool IsRedHat69 => IsDistroAndVersion("rhel", "6.9") || IsDistroAndVersion("rhl", "6.9");
public static bool IsNotRedHat69 => !IsRedHat69;
+ public static bool IsRedHat73 => IsDistroAndVersion("rhel", "7.3") || IsDistroAndVersion("rhl", "7.3");
public static Version OSXKernelVersion { get; } = GetOSXKernelVersion();
diff --git a/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs b/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs
index ce31c9965a0a..0265f84c676b 100644
--- a/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs
+++ b/src/CoreFx.Private.TestUtilities/src/System/PlatformDetection.Windows.cs
@@ -37,6 +37,7 @@ public static partial class PlatformDetection
public static bool IsNotRedHat => true;
public static bool IsRedHat69 => false;
public static bool IsNotRedHat69 => true;
+ public static bool IsRedHat73 => false;
public static bool IsWindows10Version1607OrGreater =>
GetWindowsVersion() == 10 && GetWindowsMinorVersion() == 0 && GetWindowsBuildNumber() >= 14393;
diff --git a/src/System.Drawing.Common/tests/Helpers.cs b/src/System.Drawing.Common/tests/Helpers.cs
index a1e577c41b71..f37957cb6ec4 100644
--- a/src/System.Drawing.Common/tests/Helpers.cs
+++ b/src/System.Drawing.Common/tests/Helpers.cs
@@ -15,10 +15,53 @@ public static class Helpers
public const string GdiplusIsAvailable = nameof(Helpers) + "." + nameof(GetGdiplusIsAvailable);
public const string RecentGdiplusIsAvailable = nameof(Helpers) + "." + nameof(GetRecentGdiPlusIsAvailable);
public const string RecentGdiplusIsAvailable2 = nameof(Helpers) + "." + nameof(GetRecentGdiPlusIsAvailable2);
+ public const string GdiplusIsAvailableOnWindows = nameof(Helpers) + "." + nameof(GetGdiPlusIsAvailableOnWindows);
public const string GdiPlusIsAvailableNotRedhat73 = nameof(Helpers) + "." + nameof(GetGdiPlusIsAvailableNotRedhat73);
public const string GdiPlusIsAvailableNotWindows7 = nameof(Helpers) + "." + nameof(GetGdiPlusIsAvailableNotWindows7);
public const string AnyInstalledPrinters = nameof(Helpers) + "." + nameof(IsAnyInstalledPrinters);
+ public static bool GetRecentGdiPlusIsAvailable()
+ {
+ // CentOS 7, RHEL 7 and Ubuntu 14.04 are running outdated versions of libgdiplus
+ if (PlatformDetection.IsCentos7 || PlatformDetection.IsRedHat || PlatformDetection.IsUbuntu1404)
+ {
+ return false;
+ }
+
+ return GetGdiplusIsAvailable();
+ }
+
+ public static bool GetRecentGdiPlusIsAvailable2()
+ {
+ // CentOS 7, RHEL 7 and Ubuntu 14.04, as well as Fedora 25 and OpenSUSE 4.22 are running outdated versions of libgdiplus
+ if (PlatformDetection.IsCentos7 || PlatformDetection.IsRedHat || PlatformDetection.IsUbuntu1404 || PlatformDetection.IsFedora || PlatformDetection.IsOpenSUSE)
+ {
+ return false;
+ }
+
+ return GetGdiplusIsAvailable();
+ }
+
+ public static bool GetGdiPlusIsAvailableOnWindows()
+ {
+ if (!PlatformDetection.IsWindows)
+ {
+ return false;
+ }
+
+ return GetGdiplusIsAvailable();
+ }
+
+ public static bool GetGdiPlusIsAvailableNotRedhat73()
+ {
+ if (PlatformDetection.IsRedHat)
+ {
+ return false;
+ }
+
+ return GetGdiplusIsAvailable();
+ }
+
public static bool GetGdiplusIsAvailable()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
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 6a24e7f28d99..d87cfa331589 100644
--- a/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj
+++ b/src/System.Drawing.Common/tests/System.Drawing.Common.Tests.csproj
@@ -37,6 +37,40 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -108,5 +142,8 @@
RemoteExecutorConsoleApp
+
+
+
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathIteratorTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathIteratorTest.cs
new file mode 100644
index 000000000000..2bba4b8488c1
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathIteratorTest.cs
@@ -0,0 +1,172 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Drawing2D.GraphicPathIterator unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+
+ public class GraphicsPathIteratorTest
+ {
+
+ private PointF[] pts_2f = new PointF[2] { new PointF(1, 2), new PointF(20, 30) };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Ctor_Null()
+ {
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(null))
+ {
+ Assert.Equal(0, gpi.Count);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void NextMarker_Null()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ Assert.Equal(0, gpi.NextMarker(null));
+ }
+ }
+ }
+
+ [ActiveIssue(20844)]
+ public void NextSubpath_Null()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ bool closed;
+ Assert.Equal(0, gpi.NextSubpath(null, out closed));
+ Assert.True(closed);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CopyData_NullPoints()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = null;
+ byte[] types = new byte[1];
+ Assert.Throws(() => gpi.CopyData(ref points, ref types, 0, 1));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CopyData_NullTypes()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = new PointF[1];
+ byte[] types = null;
+ Assert.Throws(() => gpi.CopyData(ref points, ref types, 0, 1));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CopyData_DifferentSize()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = new PointF[1];
+ byte[] types = new byte[2];
+ Assert.Throws(() => gpi.CopyData(ref points, ref types, 0, 1));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Enumerate_NullPoints()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = null;
+ byte[] types = new byte[2];
+ Assert.Throws(() => gpi.Enumerate(ref points, ref types));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Enumerate_NullTypes()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = new PointF[1];
+ byte[] types = null;
+ Assert.Throws(() => gpi.Enumerate(ref points, ref types));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Enumerate_DifferentSize()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (GraphicsPathIterator gpi = new GraphicsPathIterator(gp))
+ {
+ PointF[] points = new PointF[1];
+ byte[] types = new byte[2];
+ Assert.Throws(() => gpi.Enumerate(ref points, ref types));
+ }
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathTest.cs
new file mode 100644
index 000000000000..d0e649ed65ff
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/GraphicsPathTest.cs
@@ -0,0 +1,2821 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.GraphicsPath unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using SC = System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+
+ public class GraphicsPathTest
+ {
+
+ private const float Pi4 = (float)(Math.PI / 4);
+ // let's tolerate a few differences
+ private const int Precision = 3;
+ private const int LowPrecision = 1;
+
+ private void CheckEmpty(string prefix, GraphicsPath gp)
+ {
+ Assert.Equal(0, gp.PathData.Points.Length);
+ Assert.Equal(0, gp.PathData.Types.Length);
+ Assert.Equal(0, gp.PointCount);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_InvalidFillMode()
+ {
+ GraphicsPath gp = new GraphicsPath((FillMode)Int32.MinValue);
+ Assert.Equal(Int32.MinValue, (int)gp.FillMode);
+ CheckEmpty("InvalidFillMode.", gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Null_Byte()
+ {
+ Assert.Throws(() => new GraphicsPath((Point[])null, new byte[1]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Byte_Null()
+ {
+ Assert.Throws(() => new GraphicsPath(new Point[1], null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Byte_LengthMismatch()
+ {
+ Assert.Throws(() => new GraphicsPath(new Point[1], new byte[2]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_Null_Byte()
+ {
+ Assert.Throws(() => new GraphicsPath((PointF[])null, new byte[1]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_Byte_Null()
+ {
+ Assert.Throws(() => new GraphicsPath(new PointF[1], null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_Byte_LengthMismatch()
+ {
+ Assert.Throws(() => new GraphicsPath(new PointF[2], new byte[1]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GraphicsPath_Empty()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Equal(FillMode.Alternate, gp.FillMode);
+ CheckEmpty("Empty.", gp);
+
+ GraphicsPath clone = (GraphicsPath)gp.Clone();
+ Assert.Equal(FillMode.Alternate, gp.FillMode);
+ CheckEmpty("Clone.", gp);
+
+ gp.Reverse();
+ CheckEmpty("Reverse.", gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GraphicsPath_Empty_PathPoints()
+ {
+ Assert.Throws(() => Assert.Null(new GraphicsPath().PathPoints));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GraphicsPath_Empty_PathTypes()
+ {
+ Assert.Throws(() => Assert.Null(new GraphicsPath().PathTypes));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GraphicsPath_SamePoint()
+ {
+ Point[] points = new Point[] {
+ new Point (1, 1),
+ new Point (1, 1),
+ new Point (1, 1),
+ new Point (1, 1),
+ new Point (1, 1),
+ new Point (1, 1),
+ };
+ byte[] types = new byte[6] { 0, 1, 1, 1, 1, 1 };
+ using (GraphicsPath gp = new GraphicsPath(points, types))
+ {
+ Assert.Equal(6, gp.PointCount);
+ }
+ types[0] = 1;
+ using (GraphicsPath gp = new GraphicsPath(points, types))
+ {
+ Assert.Equal(6, gp.PointCount);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GraphicsPath_SamePointF()
+ {
+ PointF[] points = new PointF[] {
+ new PointF (1f, 1f),
+ new PointF (1f, 1f),
+ new PointF (1f, 1f),
+ new PointF (1f, 1f),
+ new PointF (1f, 1f),
+ new PointF (1f, 1f),
+ };
+ byte[] types = new byte[6] { 0, 1, 1, 1, 1, 1 };
+ using (GraphicsPath gp = new GraphicsPath(points, types))
+ {
+ Assert.Equal(6, gp.PointCount);
+ }
+ types[0] = 1;
+ using (GraphicsPath gp = new GraphicsPath(points, types))
+ {
+ Assert.Equal(6, gp.PointCount);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void FillMode_Invalid()
+ {
+ // constructor accept an invalid FillMode
+ GraphicsPath gp = new GraphicsPath((FillMode)Int32.MaxValue);
+ Assert.Equal(Int32.MaxValue, (int)gp.FillMode);
+ // but you can't set the FillMode property to an invalid value );-)
+ Assert.Throws(() => gp.FillMode = (FillMode)Int32.MaxValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathData_CannotChange()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+
+ Assert.Equal(1f, gp.PathData.Points[0].X);
+ Assert.Equal(1f, gp.PathData.Points[0].Y);
+
+ // now try to change the first point
+ gp.PathData.Points[0] = new Point(0, 0);
+ // the changes isn't reflected in the property
+ Assert.Equal(1f, gp.PathData.Points[0].X);
+ Assert.Equal(1f, gp.PathData.Points[0].Y);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathPoints_CannotChange()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+
+ Assert.Equal(1f, gp.PathPoints[0].X);
+ Assert.Equal(1f, gp.PathPoints[0].Y);
+
+ // now try to change the first point
+ gp.PathPoints[0] = new Point(0, 0);
+ // the changes isn't reflected in the property
+ Assert.Equal(1f, gp.PathPoints[0].X);
+ Assert.Equal(1f, gp.PathPoints[0].Y);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathTypes_CannotChange()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+
+ Assert.Equal(0, gp.PathTypes[0]);
+
+ // now try to change the first type
+ gp.PathTypes[0] = 1;
+ // the changes isn't reflected in the property
+ Assert.Equal(0, gp.PathTypes[0]);
+ }
+
+ private void CheckArc(GraphicsPath path)
+ {
+ Assert.Equal(4, path.PathPoints.Length);
+ Assert.Equal(4, path.PathTypes.Length);
+ Assert.Equal(4, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(2.99962401f, rect.X, Precision);
+ Assert.Equal(2.01370716f, rect.Y, Precision);
+ Assert.Equal(0f, rect.Width, Precision);
+ Assert.Equal(0.0137047768f, rect.Height);
+
+ Assert.Equal(2.99990582f, path.PathData.Points[0].X, Precision);
+ Assert.Equal(2.01370716f, path.PathPoints[0].Y, Precision);
+ Assert.Equal(0, path.PathData.Types[0]);
+ Assert.Equal(2.99984312f, path.PathData.Points[1].X, Precision);
+ Assert.Equal(2.018276f, path.PathPoints[1].Y, Precision);
+ Assert.Equal(3, path.PathTypes[1]);
+ Assert.Equal(2.99974918f, path.PathData.Points[2].X, Precision);
+ Assert.Equal(2.02284455f, path.PathPoints[2].Y, Precision);
+ Assert.Equal(3, path.PathData.Types[2]);
+ Assert.Equal(2.999624f, path.PathData.Points[3].X, Precision);
+ Assert.Equal(2.027412f, path.PathPoints[3].Y, Precision);
+ Assert.Equal(3, path.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddArc_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddArc(new Rectangle(1, 1, 2, 2), Pi4, Pi4);
+ CheckArc(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddArc_RectangleF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddArc(new RectangleF(1f, 1f, 2f, 2f), Pi4, Pi4);
+ CheckArc(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddArc_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddArc(1, 1, 2, 2, Pi4, Pi4);
+ CheckArc(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddArc_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4);
+ CheckArc(gp);
+ }
+
+ private void CheckBezier(GraphicsPath path)
+ {
+ Assert.Equal(4, path.PointCount);
+ Assert.Equal(4, path.PathPoints.Length);
+ Assert.Equal(4, path.PathTypes.Length);
+ Assert.Equal(4, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(3f, rect.Width);
+ Assert.Equal(3f, rect.Height);
+
+ Assert.Equal(1f, path.PathData.Points[0].X);
+ Assert.Equal(1f, path.PathPoints[0].Y);
+ Assert.Equal(0, path.PathData.Types[0]);
+ Assert.Equal(2f, path.PathData.Points[1].X);
+ Assert.Equal(2f, path.PathPoints[1].Y);
+ Assert.Equal(3, path.PathTypes[1]);
+ Assert.Equal(3f, path.PathData.Points[2].X);
+ Assert.Equal(3f, path.PathPoints[2].Y);
+ Assert.Equal(3, path.PathData.Types[2]);
+ Assert.Equal(4f, path.PathData.Points[3].X);
+ Assert.Equal(4f, path.PathPoints[3].Y);
+ Assert.Equal(3, path.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_Point()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4));
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_PointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f), new PointF(4f, 4f));
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(1, 1, 2, 2, 3, 3, 4, 4);
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(1f, 1f, 2f, 2f, 3f, 3f, 4f, 4f);
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_SamePoint()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(1, 1, 1, 1, 1, 1, 1, 1);
+ // all points are present
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(3, gp.PathTypes[1]);
+ Assert.Equal(3, gp.PathTypes[2]);
+ Assert.Equal(3, gp.PathTypes[3]);
+
+ gp.AddBezier(new Point(1, 1), new Point(1, 1), new Point(1, 1), new Point(1, 1));
+ // the first point (move to) can be compressed (i.e. removed)
+ Assert.Equal(7, gp.PointCount);
+ Assert.Equal(3, gp.PathTypes[4]);
+ Assert.Equal(3, gp.PathTypes[5]);
+ Assert.Equal(3, gp.PathTypes[6]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBezier_SamePointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBezier(new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f));
+ // all points are present
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(3, gp.PathTypes[1]);
+ Assert.Equal(3, gp.PathTypes[2]);
+ Assert.Equal(3, gp.PathTypes[3]);
+
+ gp.AddBezier(new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f));
+ // the first point (move to) can be compressed (i.e. removed)
+ Assert.Equal(7, gp.PointCount);
+ Assert.Equal(3, gp.PathTypes[4]);
+ Assert.Equal(3, gp.PathTypes[5]);
+ Assert.Equal(3, gp.PathTypes[6]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_Point_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddBeziers((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_3_Points()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddBeziers(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_Point()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBeziers(new Point[4] { new Point(1, 1), new Point(2, 2), new Point(3, 3), new Point(4, 4) });
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_PointF_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddBeziers((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_3_PointFs()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddBeziers(new PointF[3] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_PointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBeziers(new PointF[4] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f), new PointF(4f, 4f) });
+ CheckBezier(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_SamePoint()
+ {
+ Point[] points = new Point[4] { new Point(1, 1), new Point(1, 1), new Point(1, 1), new Point(1, 1) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBeziers(points);
+ // all points are present
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(3, gp.PathTypes[1]);
+ Assert.Equal(3, gp.PathTypes[2]);
+ Assert.Equal(3, gp.PathTypes[3]);
+
+ gp.AddBeziers(points);
+ // the first point (move to) can be compressed (i.e. removed)
+ Assert.Equal(7, gp.PointCount);
+ Assert.Equal(3, gp.PathTypes[4]);
+ Assert.Equal(3, gp.PathTypes[5]);
+ Assert.Equal(3, gp.PathTypes[6]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddBeziers_SamePointF()
+ {
+ PointF[] points = new PointF[4] { new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddBeziers(points);
+ // all points are present
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(3, gp.PathTypes[1]);
+ Assert.Equal(3, gp.PathTypes[2]);
+ Assert.Equal(3, gp.PathTypes[3]);
+
+ gp.AddBeziers(points);
+ // the first point (move to) can be compressed (i.e. removed)
+ Assert.Equal(7, gp.PointCount);
+ Assert.Equal(3, gp.PathTypes[4]);
+ Assert.Equal(3, gp.PathTypes[5]);
+ Assert.Equal(3, gp.PathTypes[6]);
+ }
+
+ private void CheckEllipse(GraphicsPath path)
+ {
+ Assert.Equal(13, path.PathPoints.Length);
+ Assert.Equal(13, path.PathTypes.Length);
+ Assert.Equal(13, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(2f, rect.Width);
+ Assert.Equal(2f, rect.Height);
+
+ Assert.Equal(0, path.PathData.Types[0]);
+ for (int i = 1; i < 12; i++)
+ Assert.Equal(3, path.PathTypes[i]);
+ Assert.Equal(131, path.PathData.Types[12]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddEllipse_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddEllipse(new Rectangle(1, 1, 2, 2));
+ CheckEllipse(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddEllipse_RectangleF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddEllipse(new RectangleF(1f, 1f, 2f, 2f));
+ CheckEllipse(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddEllipse_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddEllipse(1, 1, 2, 2);
+ CheckEllipse(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddEllipse_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddEllipse(1f, 1f, 2f, 2f);
+ CheckEllipse(gp);
+ }
+
+ private void CheckLine(GraphicsPath path)
+ {
+ Assert.Equal(2, path.PathPoints.Length);
+ Assert.Equal(2, path.PathTypes.Length);
+ Assert.Equal(2, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(1f, rect.Width);
+ Assert.Equal(1f, rect.Height);
+
+ Assert.Equal(1f, path.PathData.Points[0].X);
+ Assert.Equal(1f, path.PathPoints[0].Y);
+ Assert.Equal(0, path.PathData.Types[0]);
+ Assert.Equal(2f, path.PathData.Points[1].X);
+ Assert.Equal(2f, path.PathPoints[1].Y);
+ Assert.Equal(1, path.PathTypes[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_Point()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(new Point(1, 1), new Point(2, 2));
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_PointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(new PointF(1f, 1f), new PointF(2f, 2f));
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(1, 1, 2, 2);
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(1f, 1f, 2f, 2f);
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_SamePoint()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(new Point(1, 1), new Point(1, 1));
+ Assert.Equal(2, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+
+ gp.AddLine(new Point(1, 1), new Point(1, 1));
+ // 3 not 4 points, the first point (only) is compressed
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+
+ gp.AddLine(new Point(1, 1), new Point(1, 1));
+ // 4 not 5 (or 6) points, the first point (only) is compressed
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(1, gp.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_SamePointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(new PointF(49.2f, 157f), new PointF(49.2f, 157f));
+ Assert.Equal(2, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+
+ gp.AddLine(new PointF(49.2f, 157f), new PointF(49.2f, 157f));
+ // 3 not 4 points, the first point (only) is compressed
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLine_SamePointsF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLine(new PointF(49.2f, 157f), new PointF(75.6f, 196f));
+ gp.AddLine(new PointF(75.6f, 196f), new PointF(102f, 209f));
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+
+ gp.AddLine(new PointF(102f, 209f), new PointF(75.6f, 196f));
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(1, gp.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_Point_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddLines((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_Point_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddLines(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_Point_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(new Point[1] { new Point(1, 1) });
+ // Special case - a line with a single point is valid
+ Assert.Equal(1, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_Point()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(new Point[2] { new Point(1, 1), new Point(2, 2) });
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_PointF_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddLines((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_PointF_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddLines(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_PointF_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(new PointF[1] { new PointF(1f, 1f) });
+ // Special case - a line with a single point is valid
+ Assert.Equal(1, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_PointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) });
+ CheckLine(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_SamePoint()
+ {
+ Point[] points = new Point[] { new Point(1, 1), new Point(1, 1) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(points);
+ Assert.Equal(2, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+
+ gp.AddLines(points);
+ // 3 not 4 points, the first point (only) is compressed
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+
+ gp.AddLines(points);
+ // 4 not 5 (or 6) points, the first point (only) is compressed
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(1, gp.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddLines_SamePointF()
+ {
+ PointF[] points = new PointF[] { new PointF(49.2f, 157f), new PointF(49.2f, 157f), new PointF(49.2f, 157f), new PointF(49.2f, 157f) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddLines(points);
+ // all identical points are added
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(1, gp.PathTypes[3]);
+
+ gp.AddLines(points);
+ // only the first new point is compressed
+ Assert.Equal(7, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(1, gp.PathTypes[3]);
+ Assert.Equal(1, gp.PathTypes[4]);
+ Assert.Equal(1, gp.PathTypes[5]);
+ Assert.Equal(1, gp.PathTypes[6]);
+ }
+
+ private void CheckPie(GraphicsPath path)
+ {
+ // the number of points generated for a Pie isn't the same between Mono and MS
+#if false
+ Assert.Equal (5, path.PathPoints.Length);
+ Assert.Equal (5, path.PathTypes.Length);
+ Assert.Equal (5, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds ();
+ Assert.Equal (2f, rect.X);
+ Assert.Equal (2f, rect.Y);
+ Assert.Equal (0.9999058f, rect.Width);
+ Assert.Equal (0.0274119377f, rect.Height);
+
+ Assert.Equal (2f, path.PathData.Points[0].X);
+ Assert.Equal (2f, path.PathPoints[0].Y);
+ Assert.Equal (0, path.PathData.Types[0]);
+ Assert.Equal (2.99990582f, path.PathData.Points[1].X);
+ Assert.Equal (2.01370716f, path.PathPoints[1].Y);
+ Assert.Equal (1, path.PathTypes[1]);
+ Assert.Equal (2.99984312f, path.PathData.Points[2].X);
+ Assert.Equal (2.018276f, path.PathPoints[2].Y);
+ Assert.Equal (3, path.PathData.Types[2]);
+ Assert.Equal (2.99974918f, path.PathData.Points[3].X);
+ Assert.Equal (2.02284455f, path.PathPoints[3].Y);
+ Assert.Equal (3, path.PathData.Types[3]);
+ Assert.Equal (2.999624f, path.PathData.Points[4].X);
+ Assert.Equal (2.027412f, path.PathPoints[4].Y);
+ Assert.Equal (131, path.PathTypes[4]);
+#endif
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPie_Rect()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(new Rectangle(1, 1, 2, 2), Pi4, Pi4);
+ CheckPie(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPie_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(1, 1, 2, 2, Pi4, Pi4);
+ CheckPie(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPie_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(1f, 1f, 2f, 2f, Pi4, Pi4);
+ CheckPie(gp);
+ }
+
+ private void CheckPolygon(GraphicsPath path)
+ {
+ // an extra point is generated by Mono (libgdiplus)
+#if false
+ Assert.Equal (3, path.PathPoints.Length);
+ Assert.Equal (3, path.PathTypes.Length);
+ Assert.Equal (3, path.PathData.Points.Length);
+#endif
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(2f, rect.Width);
+ Assert.Equal(2f, rect.Height);
+
+ Assert.Equal(1f, path.PathData.Points[0].X);
+ Assert.Equal(1f, path.PathPoints[0].Y);
+ Assert.Equal(0, path.PathData.Types[0]);
+ Assert.Equal(2f, path.PathData.Points[1].X);
+ Assert.Equal(2f, path.PathPoints[1].Y);
+ Assert.Equal(1, path.PathTypes[1]);
+ Assert.Equal(3f, path.PathData.Points[2].X);
+ Assert.Equal(3f, path.PathPoints[2].Y);
+ // the extra point change the type of the last point
+#if false
+ Assert.Equal (129, path.PathData.Types[2]);
+#endif
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_Point_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddPolygon((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_Point_Empty()
+ {
+ Assert.Throws(() => new GraphicsPath().AddPolygon(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_Point_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddPolygon(new Point[1] { new Point(1, 1) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_Point_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddPolygon(new Point[2] { new Point(1, 1), new Point(2, 2) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_Point_3()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) });
+ CheckPolygon(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_PointF_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddPolygon((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_PointF_Empty()
+ {
+ Assert.Throws(() => new GraphicsPath().AddPolygon(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_PointF_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddPolygon(new PointF[1] { new PointF(1f, 1f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_PointF_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddPolygon(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_PointF_3()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPolygon(new PointF[3] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f) });
+ CheckPolygon(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_SamePoint()
+ {
+ Point[] points = new Point[3] { new Point(1, 1), new Point(1, 1), new Point(1, 1) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPolygon(points);
+ // all identical points are added
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(129, gp.PathTypes[2]);
+
+ gp.AddPolygon(points);
+ // all identical points are added (again)
+ Assert.Equal(6, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[3]);
+ Assert.Equal(1, gp.PathTypes[4]);
+ Assert.Equal(129, gp.PathTypes[5]);
+
+ gp.AddLines(points);
+ // all identical points are added as a line (because previous point is closed)
+ Assert.Equal(9, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[6]);
+ Assert.Equal(1, gp.PathTypes[7]);
+ Assert.Equal(1, gp.PathTypes[8]);
+
+ gp.AddPolygon(points);
+ // all identical points are added (again)
+ Assert.Equal(12, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[9]);
+ Assert.Equal(1, gp.PathTypes[10]);
+ Assert.Equal(129, gp.PathTypes[11]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPolygon_SamePointF()
+ {
+ PointF[] points = new PointF[3] { new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPolygon(points);
+ // all identical points are added
+ Assert.Equal(3, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(129, gp.PathTypes[2]);
+
+ gp.AddPolygon(points);
+ // all identical points are added (again)
+ Assert.Equal(6, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[3]);
+ Assert.Equal(1, gp.PathTypes[4]);
+ Assert.Equal(129, gp.PathTypes[5]);
+
+ gp.AddLines(points);
+ // all identical points are added as a line (because previous point is closed)
+ Assert.Equal(9, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[6]);
+ Assert.Equal(1, gp.PathTypes[7]);
+ Assert.Equal(1, gp.PathTypes[8]);
+
+ gp.AddPolygon(points);
+ // all identical points are added (again)
+ Assert.Equal(12, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[9]);
+ Assert.Equal(1, gp.PathTypes[10]);
+ Assert.Equal(129, gp.PathTypes[11]);
+ }
+
+ private void CheckRectangle(GraphicsPath path, int count)
+ {
+ Assert.Equal(count, path.PathPoints.Length);
+ Assert.Equal(count, path.PathTypes.Length);
+ Assert.Equal(count, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(2f, rect.Width);
+ Assert.Equal(2f, rect.Height);
+
+ // check first four points (first rectangle)
+ Assert.Equal(1f, path.PathData.Points[0].X);
+ Assert.Equal(1f, path.PathPoints[0].Y);
+ Assert.Equal(0, path.PathData.Types[0]);
+ Assert.Equal(3f, path.PathData.Points[1].X);
+ Assert.Equal(1f, path.PathPoints[1].Y);
+ Assert.Equal(1, path.PathTypes[1]);
+ Assert.Equal(3f, path.PathData.Points[2].X);
+ Assert.Equal(3f, path.PathPoints[2].Y);
+ Assert.Equal(1, path.PathData.Types[2]);
+ Assert.Equal(1f, path.PathData.Points[3].X);
+ Assert.Equal(3f, path.PathPoints[3].Y);
+ Assert.Equal(129, path.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangle_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+ CheckRectangle(gp, 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangle_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new RectangleF(1f, 1f, 2f, 2f));
+ CheckRectangle(gp, 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangle_SamePoint()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 0, 0));
+ Assert.Equal(0, gp.PointCount);
+
+ gp.AddRectangle(new Rectangle(1, 1, 1, 1));
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(129, gp.PathTypes[3]);
+ PointF end = gp.PathPoints[3];
+
+ // add rectangle at the last path point
+ gp.AddRectangle(new Rectangle((int)end.X, (int)end.Y, 1, 1));
+ // no compression (different type)
+ Assert.Equal(8, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(129, gp.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangle_SamePointF()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new RectangleF(1f, 1f, 0f, 0f));
+ Assert.Equal(0, gp.PointCount);
+
+ gp.AddRectangle(new RectangleF(1f, 1f, 1f, 1f));
+ Assert.Equal(4, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(129, gp.PathTypes[3]);
+ PointF end = gp.PathPoints[3];
+
+ // add rectangle at the last path point
+ gp.AddRectangle(new RectangleF(end.X, end.Y, 1f, 1f));
+ // no compression (different type)
+ Assert.Equal(8, gp.PointCount);
+ Assert.Equal(0, gp.PathTypes[0]);
+ Assert.Equal(1, gp.PathTypes[1]);
+ Assert.Equal(1, gp.PathTypes[2]);
+ Assert.Equal(129, gp.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Int_Null()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddRectangles((Rectangle[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Int_Empty()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddRectangles(new Rectangle[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Int()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangles(new Rectangle[1] { new Rectangle(1, 1, 2, 2) });
+ CheckRectangle(gp, 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Float_Null()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddRectangles((RectangleF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Float_Empty()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddRectangles(new RectangleF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Float()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangles(new RectangleF[1] { new RectangleF(1f, 1f, 2f, 2f) });
+ CheckRectangle(gp, 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_Two()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangles(new RectangleF[2] {
+ new RectangleF (1f, 1f, 2f, 2f),
+ new RectangleF (2f, 2f, 1f, 1f) });
+ RectangleF rect = gp.GetBounds();
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(1f, rect.Y);
+ Assert.Equal(2f, rect.Width);
+ Assert.Equal(2f, rect.Height);
+ // second rectangle is completely within the first one
+ CheckRectangle(gp, 8);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddRectangles_SamePoint()
+ {
+ Rectangle r1 = new Rectangle(1, 1, 0, 0);
+ Rectangle r2 = new Rectangle(1, 1, 1, 1);
+ Rectangle r3 = new Rectangle(1, 2, 1, 1);
+
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangles(new Rectangle[] { r1, r2, r3 });
+ Assert.Equal(8, gp.PointCount);
+ // first rect is ignore, then all other 2x4 (8) points are present, no compression
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPath_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddPath(null, false));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddPath()
+ {
+ GraphicsPath gpr = new GraphicsPath();
+ gpr.AddRectangle(new Rectangle(1, 1, 2, 2));
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPath(gpr, true);
+ CheckRectangle(gp, 4);
+ }
+
+ private void AssertEqualWithTolerance(float expected, float actual, float tolerance)
+ {
+ var difference = Math.Abs(expected - actual);
+ Assert.True(difference < tolerance);
+ }
+
+ private void CheckClosedCurve(GraphicsPath path)
+ {
+ Assert.Equal(10, path.PathPoints.Length);
+ Assert.Equal(10, path.PathTypes.Length);
+ Assert.Equal(10, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't very precise with curves
+ RectangleF rect = path.GetBounds();
+ AssertEqualWithTolerance(0.8333333f, rect.X, 0.2f);
+ AssertEqualWithTolerance(0.8333333f, rect.Y, 0.2f);
+ AssertEqualWithTolerance(2.33333278f, rect.Width, 0.4f);
+ AssertEqualWithTolerance(2.33333278f, rect.Height, 0.4f);
+
+ Assert.Equal(0, path.PathData.Types[0]);
+ for (int i = 1; i < 9; i++)
+ Assert.Equal(3, path.PathTypes[i]);
+ Assert.Equal(131, path.PathData.Types[9]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_Point_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddClosedCurve((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_Point_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_Point_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new Point[1] { new Point(1, 1) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_Point_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new Point[2] { new Point(1, 1), new Point(2, 2) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_Point_3()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) });
+ CheckClosedCurve(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_PointF_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddClosedCurve((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_PointF_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_PointF_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new PointF[1] { new PointF(1f, 1f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_PointF_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddClosedCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_PointF_3()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddClosedCurve(new PointF[3] { new PointF(1f, 1f), new PointF(2f, 2f), new PointF(3f, 3f) });
+ CheckClosedCurve(gp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_SamePoint()
+ {
+ Point[] points = new Point[3] { new Point(1, 1), new Point(1, 1), new Point(1, 1) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddClosedCurve(points);
+ Assert.Equal(10, gp.PointCount);
+ gp.AddClosedCurve(points);
+ Assert.Equal(20, gp.PointCount);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddClosedCurve_SamePointF()
+ {
+ PointF[] points = new PointF[3] { new PointF(1f, 1f), new PointF(1f, 1f), new PointF(1f, 1f) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddClosedCurve(points);
+ Assert.Equal(10, gp.PointCount);
+ gp.AddClosedCurve(points);
+ Assert.Equal(20, gp.PointCount);
+ }
+
+ private void CheckCurve(GraphicsPath path)
+ {
+ Assert.Equal(4, path.PathPoints.Length);
+ Assert.Equal(4, path.PathTypes.Length);
+ Assert.Equal(4, path.PathData.Points.Length);
+
+ // GetBounds (well GdipGetPathWorldBounds) isn't implemented
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(1.0f, rect.X);
+ Assert.Equal(1.0f, rect.Y);
+ Assert.Equal(1.0f, rect.Width);
+ Assert.Equal(1.0f, rect.Height);
+
+ Assert.Equal(1f, path.PathData.Points[0].X);
+ Assert.Equal(1f, path.PathPoints[0].Y);
+ Assert.Equal(0, path.PathData.Types[0]);
+ // Mono has wrong? results
+#if false
+ Assert.Equal (1.16666663f, path.PathData.Points[1].X);
+ Assert.Equal (1.16666663f, path.PathPoints[1].Y);
+#endif
+ Assert.Equal(3, path.PathTypes[1]);
+ // Mono has wrong? results
+#if false
+ Assert.Equal (1.83333325f, path.PathData.Points[2].X);
+ Assert.Equal (1.83333325f, path.PathPoints[2].Y);
+#endif
+ Assert.Equal(3, path.PathData.Types[2]);
+ Assert.Equal(2f, path.PathData.Points[3].X);
+ Assert.Equal(2f, path.PathPoints[3].Y);
+ Assert.Equal(3, path.PathTypes[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Point_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddCurve((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Point_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Point_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new Point[1] { new Point(1, 1) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Point_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new Point[2] { new Point(1, 1), new Point(2, 2) });
+ CheckCurve(gp);
+ // note: GdipAddPathCurveI allows adding a "curve" with only 2 points (a.k.a. a line );-)
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Point_2_Tension()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new Point[2] { new Point(1, 1), new Point(2, 2) }, 1.0f);
+ CheckCurve(gp);
+ // note: GdipAddPathCurve2I allows adding a "curve" with only 2 points (a.k.a. a line );-)
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve3_Point_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new Point[2] { new Point(1, 1), new Point(2, 2) }, 0, 2, 0.5f));
+ // adding only two points isn't supported by GdipAddCurve3I
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_PointF_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().AddCurve((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_PointF_0()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_PointF_1()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[1] { new PointF(1f, 1f) }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_PointF_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) });
+ CheckCurve(gp);
+ // note: GdipAddPathCurve allows adding a "curve" with only 2 points (a.k.a. a line );-)
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_PoinFt_2_Tension()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }, 1.0f);
+ CheckCurve(gp);
+ // note: GdipAddPathCurve2 allows adding a "curve" with only 2 points (a.k.a. a line );-)
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve3_PointF_2()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }, 0, 2, 0.5f));
+ // adding only two points isn't supported by GdipAddCurve3
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_LargeTension()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new PointF[3] { new PointF(1f, 1f), new PointF(0f, 20f), new PointF(20f, 0f) }, 0, 2, Single.MaxValue);
+ Assert.Equal(7, gp.PointCount);
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_ZeroSegments()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }, 0, 0, 0.5f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_NegativeSegments()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[2] { new PointF(1f, 1f), new PointF(2f, 2f) }, 0, -1, 0.5f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_OffsetTooLarge()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddCurve(new PointF[3] { new PointF(1f, 1f), new PointF(0f, 20f), new PointF(20f, 0f) }, 1, 2, 0.5f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_Offset()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(new PointF[4] { new PointF(1f, 1f), new PointF(0f, 20f), new PointF(20f, 0f), new PointF(0f, 10f) }, 1, 2, 0.5f);
+ Assert.Equal(7, gp.PointCount);
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_SamePoint()
+ {
+ Point[] points = new Point[2] { new Point(1, 1), new Point(1, 1) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(points);
+ Assert.Equal(4, gp.PointCount);
+ gp.AddCurve(points);
+ Assert.Equal(7, gp.PointCount);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddCurve_SamePointF()
+ {
+ PointF[] points = new PointF[2] { new PointF(1f, 1f), new PointF(1f, 1f) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(points);
+ Assert.Equal(4, gp.PointCount);
+ gp.AddCurve(points);
+ Assert.Equal(7, gp.PointCount);
+ }
+
+ [ActiveIssue(20844)]
+ public void AddCurve()
+ {
+ PointF[] points = new PointF[] {
+ new PointF (37f, 185f),
+ new PointF (99f, 185f),
+ new PointF (161f, 159f),
+ new PointF (223f, 185f),
+ new PointF (285f, 54f),
+ };
+ int[] count = { 4, 7, 10, 13 };
+
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ for (int i = 0; i < points.Length - 1; i++)
+ {
+ gp.AddCurve(points, i, 1, 0.5f);
+ // all non-curves points are compressed expect the first one (positioning)
+ Assert.Equal(count[i], gp.PointCount);
+ }
+
+ Assert.Equal(0, gp.PathData.Types[0]);
+ Assert.Equal(37f, gp.PathData.Points[0].X, Precision);
+ Assert.Equal(185f, gp.PathData.Points[1].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[1]);
+ Assert.Equal(47.3334f, gp.PathData.Points[1].X, Precision);
+ Assert.Equal(185f, gp.PathData.Points[1].Y, 3);
+ Assert.Equal(3, gp.PathData.Types[2]);
+ Assert.Equal(78.33333f, gp.PathData.Points[2].X, Precision);
+ Assert.Equal(189.3333f, gp.PathData.Points[2].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[3]);
+ Assert.Equal(99f, gp.PathData.Points[3].X, Precision);
+ Assert.Equal(185f, gp.PathData.Points[3].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[4]);
+ Assert.Equal(119.6667f, gp.PathData.Points[4].X, Precision);
+ Assert.Equal(180.6667f, gp.PathData.Points[4].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[5]);
+ Assert.Equal(140.3333f, gp.PathData.Points[5].X, Precision);
+ Assert.Equal(159f, gp.PathData.Points[5].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[6]);
+ Assert.Equal(161f, gp.PathData.Points[6].X, Precision);
+ Assert.Equal(159f, gp.PathData.Points[6].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[7]);
+ Assert.Equal(181.6667f, gp.PathData.Points[7].X, Precision);
+ Assert.Equal(159f, gp.PathData.Points[7].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[8]);
+ Assert.Equal(202.3333f, gp.PathData.Points[8].X, Precision);
+ Assert.Equal(202.5f, gp.PathData.Points[8].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[9]);
+ Assert.Equal(223f, gp.PathData.Points[9].X, Precision);
+ Assert.Equal(185f, gp.PathData.Points[9].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[10]);
+ Assert.Equal(243.6667f, gp.PathData.Points[10].X, Precision);
+ Assert.Equal(167.5f, gp.PathData.Points[10].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[11]);
+ Assert.Equal(274.6667f, gp.PathData.Points[11].X, Precision);
+ Assert.Equal(75.83334f, gp.PathData.Points[11].Y, Precision);
+ Assert.Equal(3, gp.PathData.Types[12]);
+ Assert.Equal(285f, gp.PathData.Points[12].X, Precision);
+ Assert.Equal(54f, gp.PathData.Points[12].Y, Precision);
+ }
+ }
+
+ private FontFamily GetFontFamily()
+ {
+ try
+ {
+ return FontFamily.GenericMonospace;
+ }
+ catch (ArgumentException)
+ {
+ Assert.True(false, "GenericMonospace FontFamily couldn't be found");
+ return null;
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddString_NullString()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ FontFamily ff = GetFontFamily();
+ Assert.Throws(() => gp.AddString(null, ff, 0, 10, new Point(10, 10), StringFormat.GenericDefault));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddString_EmptyString()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ FontFamily ff = GetFontFamily();
+ gp.AddString(String.Empty, ff, 0, 10, new Point(10, 10), StringFormat.GenericDefault);
+ Assert.Equal(0, gp.PointCount);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddString_NullFontFamily()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Assert.Throws(() => gp.AddString("mono", null, 0, 10, new Point(10, 10), StringFormat.GenericDefault));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void AddString_NegativeSize()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ FontFamily ff = GetFontFamily();
+ gp.AddString("mono", ff, 0, -10, new Point(10, 10), StringFormat.GenericDefault);
+ Assert.True(gp.PointCount > 0);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Empty_Empty()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ RectangleF rect = gp.GetBounds();
+ Assert.Equal(0.0f, rect.X);
+ Assert.Equal(0.0f, rect.Y);
+ Assert.Equal(0.0f, rect.Width);
+ Assert.Equal(0.0f, rect.Height);
+ }
+
+ private void CheckRectangleBounds(RectangleF rect)
+ {
+ Assert.Equal(1.0f, rect.X);
+ Assert.Equal(1.0f, rect.Y);
+ Assert.Equal(2.0f, rect.Width);
+ Assert.Equal(2.0f, rect.Height);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Empty_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+ CheckRectangleBounds(gp.GetBounds());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Null_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+ CheckRectangleBounds(gp.GetBounds(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_MatrixEmpty_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+ CheckRectangleBounds(gp.GetBounds(new Matrix()));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_NullNull_Rectangle()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddRectangle(new Rectangle(1, 1, 2, 2));
+ CheckRectangleBounds(gp.GetBounds(null, null));
+ }
+
+ private void CheckPieBounds(RectangleF rect)
+ {
+ Assert.Equal(60.0f, rect.X, 1);
+ Assert.Equal(60.0f, rect.Y, 1);
+ Assert.Equal(43.3f, rect.Width, 1);
+ Assert.Equal(48.3f, rect.Height, 1);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Empty_Pie()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(10, 10, 100, 100, 30, 45);
+ CheckPieBounds(gp.GetBounds());
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Null_Pie()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(10, 10, 100, 100, 30, 45);
+ CheckPieBounds(gp.GetBounds(null));
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_MatrixEmpty_Pie()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(10, 10, 100, 100, 30, 45);
+ CheckPieBounds(gp.GetBounds(new Matrix()));
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_NullNull_Pie()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddPie(10, 10, 100, 100, 30, 45);
+ CheckPieBounds(gp.GetBounds(null, null));
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetBounds_Empty_ClosedCurve()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddClosedCurve(new Point[4] { new Point (20, 100), new Point (70, 10),
+ new Point (130, 200), new Point (180, 100) });
+#if false
+ // so far from reality that it's totally useless
+ Assert.Equal (1.666666f, rect.X, 0.00001);
+ Assert.Equal (-6.66666f, rect.Y, 1);
+ Assert.Equal (196.6666f, rect.Width, 1);
+ Assert.Equal (221.6666f, rect.Height, 1);
+#endif
+ gp.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().Transform(null));
+ }
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Empty()
+ {
+ // no points in path and no exception
+ new GraphicsPath().Transform(new Matrix());
+ }
+
+ private void ComparePaths(GraphicsPath expected, GraphicsPath actual)
+ {
+ Assert.Equal(expected.PointCount, actual.PointCount);
+ for (int i = 0; i < expected.PointCount; i++)
+ {
+ Assert.Equal(expected.PathPoints[i], actual.PathPoints[i]);
+ Assert.Equal(expected.PathTypes[i], actual.PathTypes[i]);
+ }
+ }
+
+ private void CompareFlats(GraphicsPath flat, GraphicsPath original)
+ {
+ Assert.True(flat.PointCount >= original.PointCount);
+ for (int i = 0; i < flat.PointCount; i++)
+ {
+ Assert.True(flat.PathTypes[i] != 3);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Empty()
+ {
+ GraphicsPath path = new GraphicsPath();
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ // this is a no-op as there's nothing in the path
+ path.Flatten();
+ ComparePaths(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Null()
+ {
+ GraphicsPath path = new GraphicsPath();
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ // this is a no-op as there's nothing in the path
+ // an no matrix to apply
+ path.Flatten(null);
+ ComparePaths(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_NullFloat()
+ {
+ GraphicsPath path = new GraphicsPath();
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ // this is a no-op as there's nothing in the path
+ // an no matrix to apply
+ path.Flatten(null, 1f);
+ ComparePaths(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Arc()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddArc(0f, 0f, 100f, 100f, 30, 30);
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Bezier()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddBezier(0, 0, 100, 100, 30, 30, 60, 60);
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_ClosedCurve()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddClosedCurve(new Point[4] {
+ new Point (0, 0), new Point (40, 20),
+ new Point (20, 40), new Point (40, 40)
+ });
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Curve()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddCurve(new Point[4] {
+ new Point (0, 0), new Point (40, 20),
+ new Point (20, 40), new Point (40, 40)
+ });
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Ellipse()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddEllipse(10f, 10f, 100f, 100f);
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Line()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(10f, 10f, 100f, 100f);
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ ComparePaths(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Pie()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddPie(0, 0, 100, 100, 30, 30);
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ CompareFlats(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Polygon()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddPolygon(new Point[4] {
+ new Point (0, 0), new Point (10, 10),
+ new Point (20, 20), new Point (40, 40)
+ });
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ ComparePaths(path, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Flatten_Rectangle()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddRectangle(new Rectangle(0, 0, 100, 100));
+ GraphicsPath clone = (GraphicsPath)path.Clone();
+ path.Flatten();
+ ComparePaths(path, clone);
+ }
+
+ private void CheckWrap(GraphicsPath path)
+ {
+ Assert.Equal(3, path.PointCount);
+
+ PointF[] pts = path.PathPoints;
+ Assert.Equal(0, pts[0].X, Precision);
+ Assert.Equal(0, pts[0].Y, Precision);
+ Assert.Equal(0, pts[1].X, Precision);
+ Assert.Equal(0, pts[1].Y, Precision);
+ Assert.Equal(0, pts[2].X, Precision);
+ Assert.Equal(0, pts[2].Y, Precision);
+
+ byte[] types = path.PathTypes;
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[1]);
+ Assert.Equal(129, types[2]);
+ }
+
+ private void CheckWrapNaN(GraphicsPath path, bool closed)
+ {
+ Assert.Equal(3, path.PointCount);
+
+ PointF[] pts = path.PathPoints;
+ Assert.Equal(Single.NaN, pts[0].X);
+ Assert.Equal(Single.NaN, pts[0].Y);
+ Assert.Equal(Single.NaN, pts[1].X);
+ Assert.Equal(Single.NaN, pts[1].Y);
+ Assert.Equal(Single.NaN, pts[2].X);
+ Assert.Equal(Single.NaN, pts[2].Y);
+
+ byte[] types = path.PathTypes;
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[1]);
+ Assert.Equal(closed ? 129 : 1, types[2]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Warp_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().Warp(null, new RectangleF()));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Warp_NoPoints()
+ {
+ Assert.Throws(() => new GraphicsPath().Warp(new PointF[0], new RectangleF()));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Wrap_NoPoint()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Assert.Equal(0, gp.PointCount);
+
+ PointF[] pts = new PointF[1] { new PointF(0, 0) };
+ RectangleF r = new RectangleF(10, 20, 30, 40);
+ gp.Warp(pts, r, new Matrix());
+ Assert.Equal(0, gp.PointCount);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Warp_Invalid()
+ {
+ PointF[] pts = new PointF[1] { new PointF(0, 0) };
+ GraphicsPath path = new GraphicsPath();
+ path.AddPolygon(new Point[3] { new Point(5, 5), new Point(15, 5), new Point(10, 15) });
+ RectangleF r = new RectangleF(10, 20, 30, 40);
+ path.Warp(pts, r, new Matrix(), (WarpMode)Int32.MinValue);
+ Assert.Equal(0, path.PointCount);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetMarkers_EmptyPath()
+ {
+ new GraphicsPath().SetMarkers();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ClearMarkers_EmptyPath()
+ {
+ new GraphicsPath().ClearMarkers();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CloseFigure_EmptyPath()
+ {
+ new GraphicsPath().CloseFigure();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CloseAllFigures_EmptyPath()
+ {
+ new GraphicsPath().CloseAllFigures();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddArc()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddArc(10, 10, 100, 100, 90, 180);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddBezier()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddBezier(10, 10, 100, 100, 20, 20, 200, 200);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddBeziers()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddBeziers(new Point[7] { new Point (10, 10),
+ new Point (20, 10), new Point (20, 20), new Point (30, 20),
+ new Point (40, 40), new Point (50, 40), new Point (50, 50)
+ });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddClosedCurve()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddClosedCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(131, types[path.PointCount - 3]);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddCurve()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddCurve(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddEllipse()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddEllipse(10, 10, 100, 100);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(131, types[path.PointCount - 3]);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddLine()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddLine(5, 5, 10, 10);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(1, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddLines()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddLines(new Point[4] { new Point(10, 10), new Point(20, 10), new Point(20, 20), new Point(30, 20) });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(1, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddPath_Connect()
+ {
+ GraphicsPath inner = new GraphicsPath();
+ inner.AddArc(10, 10, 100, 100, 90, 180);
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddPath(inner, true);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddPath_NoConnect()
+ {
+ GraphicsPath inner = new GraphicsPath();
+ inner.AddArc(10, 10, 100, 100, 90, 180);
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddPath(inner, false);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(3, types[path.PointCount - 3]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddPie()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddPie(10, 10, 10, 10, 90, 180);
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ // libgdiplus draws pie by ending with a line (not a curve) section
+ Assert.True((types[path.PointCount - 3] & 128) == 128);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddPolygon()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddPolygon(new Point[3] { new Point(1, 1), new Point(2, 2), new Point(3, 3) });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(129, types[path.PointCount - 3]);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddRectangle()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddRectangle(new RectangleF(10, 10, 20, 20));
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(129, types[path.PointCount - 3]);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartClose_AddRectangles()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddLine(1, 1, 2, 2);
+ path.AddRectangles(new RectangleF[2] {
+ new RectangleF (10, 10, 20, 20),
+ new RectangleF (20, 20, 10, 10) });
+ path.AddLine(10, 10, 20, 20);
+ byte[] types = path.PathTypes;
+ // check first types
+ Assert.Equal(0, types[0]);
+ Assert.Equal(0, types[2]);
+ // check last types
+ Assert.Equal(129, types[path.PointCount - 3]);
+ Assert.Equal(0, types[path.PointCount - 2]);
+ Assert.Equal(1, types[path.PointCount - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Widen_Pen_Null()
+ {
+ Assert.Throws(() => new GraphicsPath().Widen(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Widen_Pen_Null_Matrix()
+ {
+ Assert.Throws(() => new GraphicsPath().Widen(null, new Matrix()));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Widen_NoPoint()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Assert.Equal(0, gp.PointCount);
+ Pen pen = new Pen(Color.Blue);
+ gp.Widen(pen);
+ Assert.Equal(0, gp.PointCount);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Widen_SinglePoint()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(new Point[1] { new Point(1, 1) });
+ // Special case - a line with a single point is valid
+ Assert.Equal(1, gp.PointCount);
+ Assert.Throws(() => gp.Widen(Pens.Red));
+ // oops );-)
+ }
+ }
+
+ private void CheckWiden3(GraphicsPath path)
+ {
+ PointF[] pts = path.PathPoints;
+ Assert.Equal(4.2, pts[0].X, LowPrecision);
+ Assert.Equal(4.5, pts[0].Y, LowPrecision);
+ Assert.Equal(15.8, pts[1].X, LowPrecision);
+ Assert.Equal(4.5, pts[1].Y, LowPrecision);
+ Assert.Equal(10.0, pts[2].X, LowPrecision);
+ Assert.Equal(16.1, pts[2].Y, LowPrecision);
+ Assert.Equal(10.4, pts[3].X, LowPrecision);
+ Assert.Equal(14.8, pts[3].Y, LowPrecision);
+ Assert.Equal(9.6, pts[4].X, LowPrecision);
+ Assert.Equal(14.8, pts[4].Y, LowPrecision);
+ Assert.Equal(14.6, pts[5].X, LowPrecision);
+ Assert.Equal(4.8, pts[5].Y, LowPrecision);
+ Assert.Equal(15.0, pts[6].X, LowPrecision);
+ Assert.Equal(5.5, pts[6].Y, LowPrecision);
+ Assert.Equal(5.0, pts[7].X, LowPrecision);
+ Assert.Equal(5.5, pts[7].Y, LowPrecision);
+ Assert.Equal(5.4, pts[8].X, LowPrecision);
+ Assert.Equal(4.8, pts[8].Y, LowPrecision);
+
+ byte[] types = path.PathTypes;
+ Assert.Equal(0, types[0]);
+ Assert.Equal(1, types[1]);
+ Assert.Equal(129, types[2]);
+ Assert.Equal(0, types[3]);
+ Assert.Equal(1, types[4]);
+ Assert.Equal(1, types[5]);
+ Assert.Equal(1, types[6]);
+ Assert.Equal(1, types[7]);
+ Assert.Equal(129, types[8]);
+ }
+
+ private void CheckWidenedBounds(string message, GraphicsPath gp, Matrix m)
+ {
+ RectangleF bounds = gp.GetBounds(m);
+ Assert.Equal(0.5f, bounds.X, Precision);
+ Assert.Equal(0.5f, bounds.Y, Precision);
+ Assert.Equal(3.0f, bounds.Width, Precision);
+ Assert.Equal(3.0f, bounds.Height, Precision);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_IntNull()
+ {
+ Assert.Throws(() => new GraphicsPath().IsOutlineVisible(1, 1, null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_FloatNull()
+ {
+ Assert.Throws(() => new GraphicsPath().IsOutlineVisible(1.0f, 1.0f, null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_PointNull()
+ {
+ Assert.Throws(() => new GraphicsPath().IsOutlineVisible(new Point(), null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_PointFNull()
+ {
+ Assert.Throws(() => new GraphicsPath().IsOutlineVisible(new PointF(), null));
+ }
+
+ private void IsOutlineVisible_Line(Graphics graphics)
+ {
+ Pen p2 = new Pen(Color.Red, 3.0f);
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLine(10, 1, 14, 1);
+ Assert.True(gp.IsOutlineVisible(10, 1, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(10, 2, p2, graphics));
+ Assert.False(gp.IsOutlineVisible(10, 2, Pens.Red, graphics));
+
+ Assert.True(gp.IsOutlineVisible(11.0f, 1.0f, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(11.0f, 1.0f, p2, graphics));
+ Assert.False(gp.IsOutlineVisible(11.0f, 2.0f, Pens.Red, graphics));
+
+ Point pt = new Point(12, 2);
+ Assert.False(gp.IsOutlineVisible(pt, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(pt, p2, graphics));
+ pt.Y = 1;
+ Assert.True(gp.IsOutlineVisible(pt, Pens.Red, graphics));
+
+ PointF pf = new PointF(13.0f, 2.0f);
+ Assert.False(gp.IsOutlineVisible(pf, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(pf, p2, graphics));
+ pf.Y = 1;
+ Assert.True(gp.IsOutlineVisible(pf, Pens.Red, graphics));
+ }
+ p2.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithoutGraphics()
+ {
+ IsOutlineVisible_Line(null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithGraphics_Inside()
+ {
+ using (Bitmap bitmap = new Bitmap(20, 20))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ IsOutlineVisible_Line(g);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithGraphics_Outside()
+ {
+ using (Bitmap bitmap = new Bitmap(5, 5))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ IsOutlineVisible_Line(g);
+ }
+ // graphics "seems" ignored as the line is outside the bitmap!
+ }
+ }
+
+ // docs ways the point is in world coordinates and that the graphics transform
+ // should be applied
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithGraphics_Transform()
+ {
+ using (Bitmap bitmap = new Bitmap(20, 20))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ g.Transform = new Matrix(2, 0, 0, 2, 50, -50);
+ IsOutlineVisible_Line(g);
+ }
+ // graphics still "seems" ignored (Transform)
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithGraphics_PageUnit()
+ {
+ using (Bitmap bitmap = new Bitmap(20, 20))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ g.PageUnit = GraphicsUnit.Millimeter;
+ IsOutlineVisible_Line(g);
+ }
+ // graphics still "seems" ignored (PageUnit)
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Line_WithGraphics_PageScale()
+ {
+ using (Bitmap bitmap = new Bitmap(20, 20))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ g.PageScale = 2.0f;
+ IsOutlineVisible_Line(g);
+ }
+ // graphics still "seems" ignored (PageScale)
+ }
+ }
+
+ private void IsOutlineVisible_Rectangle(Graphics graphics)
+ {
+ Pen p2 = new Pen(Color.Red, 3.0f);
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddRectangle(new Rectangle(10, 10, 20, 20));
+ Assert.True(gp.IsOutlineVisible(10, 10, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(10, 11, p2, graphics));
+ Assert.False(gp.IsOutlineVisible(11, 11, Pens.Red, graphics));
+
+ Assert.True(gp.IsOutlineVisible(11.0f, 10.0f, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(11.0f, 11.0f, p2, graphics));
+ Assert.False(gp.IsOutlineVisible(11.0f, 11.0f, Pens.Red, graphics));
+
+ Point pt = new Point(15, 10);
+ Assert.True(gp.IsOutlineVisible(pt, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(pt, p2, graphics));
+ pt.Y = 15;
+ Assert.False(gp.IsOutlineVisible(pt, Pens.Red, graphics));
+
+ PointF pf = new PointF(29.0f, 29.0f);
+ Assert.False(gp.IsOutlineVisible(pf, Pens.Red, graphics));
+ Assert.True(gp.IsOutlineVisible(pf, p2, graphics));
+ pf.Y = 31.0f;
+ Assert.True(gp.IsOutlineVisible(pf, p2, graphics));
+ }
+ p2.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOutlineVisible_Rectangle_WithoutGraphics()
+ {
+ IsOutlineVisible_Rectangle(null);
+ }
+
+ private void IsVisible_Rectangle(Graphics graphics)
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddRectangle(new Rectangle(10, 10, 20, 20));
+ Assert.False(gp.IsVisible(9, 9, graphics));
+ Assert.True(gp.IsVisible(10, 10, graphics));
+ Assert.True(gp.IsVisible(20, 20, graphics));
+ Assert.True(gp.IsVisible(29, 29, graphics));
+ Assert.False(gp.IsVisible(30, 29, graphics));
+ Assert.False(gp.IsVisible(29, 30, graphics));
+ Assert.False(gp.IsVisible(30, 30, graphics));
+
+ Assert.False(gp.IsVisible(9.4f, 9.4f, graphics));
+ Assert.True(gp.IsVisible(9.5f, 9.5f, graphics));
+ Assert.True(gp.IsVisible(10f, 10f, graphics));
+ Assert.True(gp.IsVisible(20f, 20f, graphics));
+ // the next diff is too close, so this fails with libgdiplus/cairo
+ //Assert.True (gp.IsVisible (29.4f, 29.4f, graphics));
+ Assert.False(gp.IsVisible(29.5f, 29.5f, graphics));
+ Assert.False(gp.IsVisible(29.5f, 29.4f, graphics));
+ Assert.False(gp.IsVisible(29.4f, 29.5f, graphics));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsVisible_Rectangle_WithoutGraphics()
+ {
+ IsVisible_Rectangle(null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsVisible_Rectangle_WithGraphics()
+ {
+ using (Bitmap bitmap = new Bitmap(40, 40))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ IsVisible_Rectangle(g);
+ }
+ }
+ }
+
+ // bug #325502 has shown that ellipse didn't work with earlier code
+ private void IsVisible_Ellipse(Graphics graphics)
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddEllipse(new Rectangle(10, 10, 20, 20));
+ Assert.False(gp.IsVisible(10, 10, graphics));
+ Assert.True(gp.IsVisible(20, 20, graphics));
+ Assert.False(gp.IsVisible(29, 29, graphics));
+
+ Assert.False(gp.IsVisible(10f, 10f, graphics));
+ Assert.True(gp.IsVisible(20f, 20f, graphics));
+ Assert.False(gp.IsVisible(29.4f, 29.4f, graphics));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsVisible_Ellipse_WithoutGraphics()
+ {
+ IsVisible_Ellipse(null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsVisible_Ellipse_WithGraphics()
+ {
+ using (Bitmap bitmap = new Bitmap(40, 40))
+ {
+ using (Graphics g = Graphics.FromImage(bitmap))
+ {
+ IsVisible_Ellipse(g);
+ }
+ }
+ }
+
+ // Reverse simple test cases
+
+ private void Reverse(GraphicsPath gp)
+ {
+ PointF[] bp = gp.PathPoints;
+ byte[] bt = gp.PathTypes;
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(bt[i], at[i]);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Arc()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Bezier()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddBezier(1, 2, 3, 4, 5, 6, 7, 8);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Beziers()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Point[] beziers = new Point[] { new Point (1,2), new Point (3,4), new Point (5,6),
+ new Point (7,8), new Point (9,10), new Point (11,12), new Point (13,14) };
+ gp.AddBeziers(beziers);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_ClosedCurve()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Point[] beziers = new Point[] { new Point (1,2), new Point (3,4), new Point (5,6),
+ new Point (7,8), new Point (9,10), new Point (11,12), new Point (13,14) };
+ gp.AddClosedCurve(beziers);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Curve()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Point[] beziers = new Point[] { new Point (1,2), new Point (3,4), new Point (5,6),
+ new Point (7,8), new Point (9,10), new Point (11,12), new Point (13,14) };
+ gp.AddCurve(beziers);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Ellipse()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddEllipse(1, 2, 3, 4);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Line()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLine(1, 2, 3, 4);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Line_Closed()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLine(1, 2, 3, 4);
+ gp.CloseFigure();
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Lines()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Point[] points = new Point[] { new Point (1,2), new Point (3,4), new Point (5,6),
+ new Point (7,8), new Point (9,10), new Point (11,12), new Point (13,14) };
+ gp.AddLines(points);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Polygon()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Point[] points = new Point[] { new Point (1,2), new Point (3,4), new Point (5,6),
+ new Point (7,8), new Point (9,10), new Point (11,12), new Point (13,14) };
+ gp.AddPolygon(points);
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Rectangle()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddRectangle(new Rectangle(1, 2, 3, 4));
+ Reverse(gp);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Rectangles()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Rectangle[] rects = new Rectangle[] { new Rectangle(1, 2, 3, 4), new Rectangle(5, 6, 7, 8) };
+ gp.AddRectangles(rects);
+ Reverse(gp);
+ }
+ }
+
+ // Reverse complex test cases
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Path()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddArc(1f, 1f, 2f, 2f, Pi4, Pi4);
+ path.AddLine(1, 2, 3, 4);
+ gp.AddPath(path, true);
+ PointF[] bp = gp.PathPoints;
+ byte[] expected = new byte[] { 0, 1, 1, 3, 3, 3 };
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(expected[i], at[i]);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Path_2()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddEllipse(50, 51, 50, 100);
+ gp.AddRectangle(new Rectangle(200, 201, 60, 61));
+ PointF[] bp = gp.PathPoints;
+ byte[] expected = new byte[] { 0, 1, 1, 129, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 131 };
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(expected[i], at[i]);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Marker()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddRectangle(new Rectangle(200, 201, 60, 61));
+ gp.SetMarkers();
+ PointF[] bp = gp.PathPoints;
+ byte[] expected = new byte[] { 0, 1, 1, 129 };
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(expected[i], at[i]);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Subpath_Marker()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLine(0, 1, 2, 3);
+ gp.SetMarkers();
+ gp.CloseFigure();
+ gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12);
+ gp.CloseFigure();
+ PointF[] bp = gp.PathPoints;
+ byte[] expected = new byte[] { 0, 3, 3, 163, 0, 129 };
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(expected[i], at[i]);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reverse_Subpath_Marker_2()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLine(0, 1, 2, 3);
+ gp.SetMarkers();
+ gp.StartFigure();
+ gp.AddLine(20, 21, 22, 23);
+ gp.AddBezier(5, 6, 7, 8, 9, 10, 11, 12);
+ PointF[] bp = gp.PathPoints;
+ byte[] expected = new byte[] { 0, 3, 3, 3, 1, 33, 0, 1 };
+
+ gp.Reverse();
+ PointF[] ap = gp.PathPoints;
+ byte[] at = gp.PathTypes;
+
+ int count = gp.PointCount;
+ Assert.Equal(bp.Length, count);
+ for (int i = 0; i < count; i++)
+ {
+ Assert.Equal(bp[i], ap[count - i - 1]);
+ Assert.Equal(expected[i], at[i]);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void bug413461()
+ {
+ int dX = 520;
+ int dY = 320;
+ Point[] expected_points = new Point[] {
+ new Point(dX-64, dY-24),//start
+ new Point(dX-59, dY-34),//focal point 1
+ new Point(dX-52, dY-54),//focal point 2
+ new Point(dX-18, dY-66),//top
+ new Point(dX-34, dY-47),//focal point 1
+ new Point(dX-43, dY-27),//focal point 2
+ new Point(dX-44, dY-8),//end
+ };
+ byte[] expected_types = new byte[] {
+ (byte)PathPointType.Start,
+ (byte)PathPointType.Bezier,
+ (byte)PathPointType.Bezier,
+ (byte)PathPointType.Bezier,
+ (byte)PathPointType.Bezier,
+ (byte)PathPointType.Bezier,
+ (byte)PathPointType.Bezier };
+ using (GraphicsPath path = new GraphicsPath(expected_points, expected_types))
+ {
+ Assert.Equal(7, path.PointCount);
+ byte[] actual_types = path.PathTypes;
+ Assert.Equal(expected_types[0], actual_types[0]);
+ Assert.Equal(expected_types[1], actual_types[1]);
+ Assert.Equal(expected_types[2], actual_types[2]);
+ Assert.Equal(expected_types[3], actual_types[3]);
+ Assert.Equal(expected_types[4], actual_types[4]);
+ Assert.Equal(expected_types[5], actual_types[5]);
+ // path is filled like closed but this does not show on the type
+ Assert.Equal(expected_types[6], actual_types[6]);
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/LinearGradientBrushTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/LinearGradientBrushTest.cs
new file mode 100644
index 000000000000..1aa2aa21a015
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/LinearGradientBrushTest.cs
@@ -0,0 +1,862 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Drawing2D.LinearGradientBrush unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006, 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+
+ public class LinearGradientBrushTest
+ {
+
+ private Point pt1;
+ private Point pt2;
+ private Color c1;
+ private Color c2;
+ private LinearGradientBrush default_brush;
+ private Matrix empty_matrix;
+ private RectangleF rect;
+
+ public LinearGradientBrushTest()
+ {
+ pt1 = new Point(0, 0);
+ pt2 = new Point(32, 32);
+ c1 = Color.Blue;
+ c2 = Color.Red;
+ default_brush = new LinearGradientBrush(pt1, pt2, c1, c2);
+ empty_matrix = new Matrix();
+ rect = new RectangleF(0, 0, 32, 32);
+ }
+
+ private void CheckDefaultRectangle(string msg, RectangleF rect)
+ {
+ Assert.Equal(pt1.X, rect.X);
+ Assert.Equal(pt1.Y, rect.Y);
+ Assert.Equal(pt2.X, rect.Width);
+ Assert.Equal(pt2.Y, rect.Height);
+ }
+
+ private void CheckDefaultMatrix(Matrix matrix)
+ {
+ float[] elements = matrix.Elements;
+ Assert.Equal(1.0f, elements[0], 1);
+ Assert.Equal(1.0f, elements[1], 1);
+ Assert.Equal(-1.0f, elements[2], 1);
+ Assert.Equal(1.0f, elements[3], 1);
+ Assert.Equal(16.0f, elements[4], 1);
+ Assert.Equal(-16.0f, elements[5], 1);
+ }
+
+ private void CheckBrushAt45(LinearGradientBrush lgb)
+ {
+ CheckDefaultRectangle("4", lgb.Rectangle);
+ Assert.Equal(1, lgb.Blend.Factors.Length);
+ Assert.Equal(1, lgb.Blend.Factors[0]);
+ Assert.Equal(1, lgb.Blend.Positions.Length);
+ // lgb.Blend.Positions [0] is always small (e-39) but never quite the same
+ Assert.False(lgb.GammaCorrection);
+ Assert.Equal(2, lgb.LinearColors.Length);
+ Assert.NotNull(lgb.Transform);
+ CheckDefaultMatrix(lgb.Transform);
+ }
+
+ private void CheckMatrixAndRect(PointF pt1, PointF pt2, float[] testVals)
+ {
+ Matrix m;
+ RectangleF rect;
+
+ using (LinearGradientBrush b = new LinearGradientBrush(pt1, pt2, Color.Black, Color.White))
+ {
+ m = b.Transform;
+ rect = b.Rectangle;
+ }
+
+ Assert.Equal(testVals[0], m.Elements[0], 3);
+ Assert.Equal(testVals[1], m.Elements[1], 3);
+ Assert.Equal(testVals[2], m.Elements[2], 3);
+ Assert.Equal(testVals[3], m.Elements[3], 3);
+ Assert.Equal(testVals[4], m.Elements[4], 3);
+ Assert.Equal(testVals[5], m.Elements[5], 3);
+
+ Assert.Equal(testVals[6], rect.X, 3);
+ Assert.Equal(testVals[7], rect.Y, 3);
+ Assert.Equal(testVals[8], rect.Width, 3);
+ Assert.Equal(testVals[9], rect.Height, 3);
+ }
+
+ private void CheckMatrixForScalableAngle(RectangleF rect, float angle, float[] testVals)
+ {
+ Matrix m;
+
+ using (LinearGradientBrush b = new LinearGradientBrush(rect, Color.Firebrick, Color.Lavender, angle, true))
+ {
+ m = b.Transform;
+ }
+
+ Assert.Equal(testVals[0], m.Elements[0], 3);
+ Assert.Equal(testVals[1], m.Elements[1], 3);
+ Assert.Equal(testVals[2], m.Elements[2], 3);
+ Assert.Equal(testVals[3], m.Elements[3], 3);
+ Assert.Equal(testVals[4], m.Elements[4], 3);
+ Assert.Equal(testVals[5], m.Elements[5], 3);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Point_Color_Color()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ CheckBrushAt45(lgb);
+
+ Assert.Equal(WrapMode.Tile, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipX;
+ Assert.Equal(WrapMode.TileFlipX, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipY;
+ Assert.Equal(WrapMode.TileFlipY, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipXY;
+ Assert.Equal(WrapMode.TileFlipXY, lgb.WrapMode);
+ // can't set WrapMode.Clamp
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Point_Color_Color_1()
+ {
+ PointF pt1 = new Point(100, 200);
+ PointF pt2 = new Point(200, 200);
+ CheckMatrixAndRect(pt1, pt2, new float[] { 1, 0, 0, 1, 0, 0, 100, 150, 100, 100 });
+
+ pt1 = new Point(100, 200);
+ pt2 = new Point(0, 200);
+ CheckMatrixAndRect(pt1, pt2, new float[] { -1, 0, 0, -1, 100, 400, 0, 150, 100, 100 });
+
+ pt1 = new Point(100, 200);
+ pt2 = new Point(100, 300);
+ CheckMatrixAndRect(pt1, pt2, new float[] { 0, 1, -1, 0, 350, 150, 50, 200, 100, 100 });
+
+ pt1 = new Point(100, 200);
+ pt2 = new Point(100, 100);
+ CheckMatrixAndRect(pt1, pt2, new float[] { 0, -1, 1, 0, -50, 250, 50, 100, 100, 100 });
+
+ pt1 = new Point(100, 100);
+ pt2 = new Point(150, 225);
+ CheckMatrixAndRect(pt1, pt2, new float[] { 1, 2.5f, -0.6896552f, 0.2758622f, 112.069f, -194.8276f, 100, 100, 50, 125 });
+
+ pt1 = new Point(100, 100);
+ pt2 = new Point(55, 200);
+ CheckMatrixAndRect(pt1, pt2, new float[] { -1, 2.222222f, -0.7484408f, -0.3367983f, 267.2661f, 28.29753f, 55, 100, 45, 100 });
+
+ pt1 = new Point(100, 100);
+ pt2 = new Point(150, 60);
+ CheckMatrixAndRect(pt1, pt2, new float[] { 1, -0.8000001f, 0.9756095f, 1.219512f, -78.04876f, 82.43903f, 100, 60, 50, 40 });
+
+ pt1 = new Point(100, 100);
+ pt2 = new Point(27, 59);
+ CheckMatrixAndRect(pt1, pt2, new float[] { -1, -0.5616435f, 0.8539224f, -1.520399f, 59.11317f, 236.0361f, 27, 59, 73, 41 });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_0()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ Assert.Equal(1, lgb.Blend.Factors.Length);
+ Assert.Equal(1, lgb.Blend.Factors[0]);
+ Assert.Equal(1, lgb.Blend.Positions.Length);
+ // lgb.Blend.Positions [0] is always small (e-39) but never quite the same
+ Assert.False(lgb.GammaCorrection);
+ Assert.Equal(c1.ToArgb(), lgb.LinearColors[0].ToArgb());
+ Assert.Equal(c2.ToArgb(), lgb.LinearColors[1].ToArgb());
+ Assert.Equal(rect, lgb.Rectangle);
+ Assert.True(lgb.Transform.IsIdentity);
+ Assert.Equal(WrapMode.Tile, lgb.WrapMode);
+
+ Matrix matrix = new Matrix(2, -1, 1, 2, 10, 10);
+ lgb.Transform = matrix;
+ Assert.Equal(matrix, lgb.Transform);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_22_5()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 22.5f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(1.207107, elements[0], 4);
+ Assert.Equal(0.5, elements[1], 4);
+ Assert.Equal(-0.5, elements[2], 4);
+ Assert.Equal(1.207107, elements[3], 4);
+ Assert.Equal(4.686291, elements[4], 4);
+ Assert.Equal(-11.313709, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_45()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 45f);
+ CheckBrushAt45(lgb);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_90()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 90f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(0, elements[0], 4);
+ Assert.Equal(1, elements[1], 4);
+ Assert.Equal(-1, elements[2], 4);
+ Assert.Equal(0, elements[3], 4);
+ Assert.Equal(32, elements[4], 4);
+ Assert.Equal(0, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_135()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 135f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(-1, elements[0], 4);
+ Assert.Equal(1, elements[1], 4);
+ Assert.Equal(-1, elements[2], 4);
+ Assert.Equal(-1, elements[3], 4);
+ Assert.Equal(48, elements[4], 4);
+ Assert.Equal(16, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_180()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 180f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(-1, elements[0], 4);
+ Assert.Equal(0, elements[1], 4);
+ Assert.Equal(0, elements[2], 4);
+ Assert.Equal(-1, elements[3], 4);
+ Assert.Equal(32, elements[4], 4);
+ Assert.Equal(32, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_270()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 270f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(0, elements[0], 4);
+ Assert.Equal(-1, elements[1], 4);
+ Assert.Equal(1, elements[2], 4);
+ Assert.Equal(0, elements[3], 4);
+ Assert.Equal(0, elements[4], 4);
+ Assert.Equal(32, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_315()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 315f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(1, elements[0], 4);
+ Assert.Equal(-1, elements[1], 4);
+ Assert.Equal(1, elements[2], 4);
+ Assert.Equal(1, elements[3], 4);
+ Assert.Equal(-16, elements[4], 4);
+ Assert.Equal(16, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_360()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 360f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ // just like 0'
+ Assert.Equal(1, elements[0], 4);
+ Assert.Equal(0, elements[1], 4);
+ Assert.Equal(0, elements[2], 4);
+ Assert.Equal(1, elements[3], 4);
+ Assert.Equal(0, elements[4], 4);
+ Assert.Equal(0, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectangleF_Color_Color_Single_540()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 540f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ float[] elements = lgb.Transform.Elements;
+ // just like 180'
+ Assert.Equal(-1, elements[0], 4);
+ Assert.Equal(0, elements[1], 4);
+ Assert.Equal(0, elements[2], 4);
+ Assert.Equal(-1, elements[3], 4);
+ Assert.Equal(32, elements[4], 4);
+ Assert.Equal(32, elements[5], 4);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void InterpolationColors_Colors_InvalidBlend()
+ {
+ // default Blend doesn't allow getting this property
+ Assert.Throws(() => { var x = default_brush.InterpolationColors.Colors; });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void InterpolationColors_Positions_InvalidBlend()
+ {
+ // default Blend doesn't allow getting this property
+ Assert.Throws(() => { var x = default_brush.InterpolationColors.Positions; });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LinearColors_Empty()
+ {
+ Assert.Throws(() => default_brush.LinearColors = new Color[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LinearColors_One()
+ {
+ Assert.Throws(() => default_brush.LinearColors = new Color[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LinearColors_Two()
+ {
+ Assert.Equal(Color.FromArgb(255, 0, 0, 255), default_brush.LinearColors[0]);
+ Assert.Equal(Color.FromArgb(255, 255, 0, 0), default_brush.LinearColors[1]);
+
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ lgb.LinearColors = new Color[2] { Color.Black, Color.White };
+ // not the same, the alpha is changed to 255 so they can't compare
+ Assert.Equal(Color.FromArgb(255, 0, 0, 0), lgb.LinearColors[0]);
+ Assert.Equal(Color.FromArgb(255, 255, 255, 255), lgb.LinearColors[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LinearColors_Three()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ lgb.LinearColors = new Color[3] { Color.Red, Color.Green, Color.Blue };
+ // not the same, the alpha is changed to 255 so they can't compare
+ Assert.Equal(Color.FromArgb(255, 255, 0, 0), lgb.LinearColors[0]);
+ Assert.Equal(Color.FromArgb(255, 0, 128, 0), lgb.LinearColors[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rectangle()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ CheckDefaultRectangle("Original", lgb.Rectangle);
+ lgb.MultiplyTransform(new Matrix(2, 0, 0, 2, 2, 2));
+ CheckDefaultRectangle("Multiply", lgb.Rectangle);
+ lgb.ResetTransform();
+ CheckDefaultRectangle("Reset", lgb.Rectangle);
+ lgb.RotateTransform(90);
+ CheckDefaultRectangle("Rotate", lgb.Rectangle);
+ lgb.ScaleTransform(4, 0.25f);
+ CheckDefaultRectangle("Scale", lgb.Rectangle);
+ lgb.TranslateTransform(-10, -20);
+ CheckDefaultRectangle("Translate", lgb.Rectangle);
+
+ lgb.SetBlendTriangularShape(0.5f);
+ CheckDefaultRectangle("SetBlendTriangularShape", lgb.Rectangle);
+ lgb.SetSigmaBellShape(0.5f);
+ CheckDefaultRectangle("SetSigmaBellShape", lgb.Rectangle);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Null()
+ {
+ Assert.Throws(() => default_brush.Transform = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Empty()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ lgb.Transform = new Matrix();
+ Assert.True(lgb.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_NonInvertible()
+ {
+ Assert.Throws(() => default_brush.Transform = new Matrix(123, 24, 82, 16, 47, 30));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WrapMode_AllValid()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ lgb.WrapMode = WrapMode.Tile;
+ Assert.Equal(WrapMode.Tile, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipX;
+ Assert.Equal(WrapMode.TileFlipX, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipY;
+ Assert.Equal(WrapMode.TileFlipY, lgb.WrapMode);
+ lgb.WrapMode = WrapMode.TileFlipXY;
+ Assert.Equal(WrapMode.TileFlipXY, lgb.WrapMode);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WrapMode_Clamp()
+ {
+ Assert.Throws(() => default_brush.WrapMode = WrapMode.Clamp);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void WrapMode_Invalid()
+ {
+ Assert.Throws(() => default_brush.WrapMode = (WrapMode)Int32.MinValue);
+ }
+
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ LinearGradientBrush clone = (LinearGradientBrush)lgb.Clone();
+ Assert.Equal(lgb.Blend.Factors.Length, clone.Blend.Factors.Length);
+ Assert.Equal(lgb.Blend.Positions.Length, clone.Blend.Positions.Length);
+ Assert.Equal(lgb.GammaCorrection, clone.GammaCorrection);
+ Assert.Equal(lgb.LinearColors.Length, clone.LinearColors.Length);
+ Assert.Equal(lgb.LinearColors.Length, clone.LinearColors.Length);
+ Assert.Equal(lgb.Rectangle, clone.Rectangle);
+ Assert.Equal(lgb.Transform, clone.Transform);
+ Assert.Equal(lgb.WrapMode, clone.WrapMode);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform1_Null()
+ {
+ Assert.Throws(() => default_brush.MultiplyTransform(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform2_Null()
+ {
+ Assert.Throws(() => default_brush.MultiplyTransform(null, MatrixOrder.Append));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform2_Invalid()
+ {
+ default_brush.MultiplyTransform(empty_matrix, (MatrixOrder)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform_NonInvertible()
+ {
+ Matrix noninvertible = new Matrix(123, 24, 82, 16, 47, 30);
+ Assert.Throws(() => default_brush.MultiplyTransform(noninvertible));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ResetTransform()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ Assert.False(lgb.Transform.IsIdentity);
+ lgb.ResetTransform();
+ Assert.True(lgb.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ lgb.RotateTransform(90);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(0, elements[0], 1);
+ Assert.Equal(1, elements[1], 1);
+ Assert.Equal(-1, elements[2], 1);
+ Assert.Equal(0, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ lgb.RotateTransform(270);
+ Assert.True(lgb.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform_InvalidOrder()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ Assert.Throws(() => lgb.RotateTransform(720, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ lgb.ScaleTransform(2, 4);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(2, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(4, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ lgb.ScaleTransform(0.5f, 0.25f);
+ Assert.True(lgb.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_45()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 45f);
+ lgb.ScaleTransform(3, 3);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(3, elements[0], 1);
+ Assert.Equal(3, elements[1], 1);
+ Assert.Equal(-3, elements[2], 1);
+ Assert.Equal(3, elements[3], 1);
+ Assert.Equal(16, elements[4], 1);
+ Assert.Equal(-16, elements[5], 1);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_MaxMin()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ lgb.ScaleTransform(Single.MaxValue, Single.MinValue);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(Single.MaxValue, elements[0]);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(Single.MinValue, elements[3]);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_InvalidOrder()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ Assert.Throws(() => lgb.ScaleTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_Focus()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ // max valid
+ lgb.SetBlendTriangularShape(1);
+ Assert.True(lgb.Transform.IsIdentity);
+ // min valid
+ lgb.SetBlendTriangularShape(0);
+ Assert.True(lgb.Transform.IsIdentity);
+ // middle
+ lgb.SetBlendTriangularShape(0.5f);
+ Assert.True(lgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_Scale()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ // max valid
+ lgb.SetBlendTriangularShape(0, 1);
+ Assert.True(lgb.Transform.IsIdentity);
+ // min valid
+ lgb.SetBlendTriangularShape(1, 0);
+ Assert.True(lgb.Transform.IsIdentity);
+ // middle
+ lgb.SetBlendTriangularShape(0.5f, 0.5f);
+ Assert.True(lgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_FocusTooSmall()
+ {
+ Assert.Throws(() => default_brush.SetBlendTriangularShape(-1));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_FocusTooBig()
+ {
+ Assert.Throws(() => default_brush.SetBlendTriangularShape(1.01f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_ScaleTooSmall()
+ {
+ Assert.Throws(() => default_brush.SetBlendTriangularShape(1, -1));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_ScaleTooBig()
+ {
+ Assert.Throws(() => default_brush.SetBlendTriangularShape(1, 1.01f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_Focus()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ // max valid
+ lgb.SetSigmaBellShape(1);
+ Assert.True(lgb.Transform.IsIdentity);
+ // min valid
+ lgb.SetSigmaBellShape(0);
+ Assert.True(lgb.Transform.IsIdentity);
+ // middle
+ lgb.SetSigmaBellShape(0.5f);
+ Assert.True(lgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_Scale()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ // max valid
+ lgb.SetSigmaBellShape(0, 1);
+ Assert.True(lgb.Transform.IsIdentity);
+ // min valid
+ lgb.SetSigmaBellShape(1, 0);
+ Assert.True(lgb.Transform.IsIdentity);
+ // middle
+ lgb.SetSigmaBellShape(0.5f, 0.5f);
+ Assert.True(lgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_FocusTooSmall()
+ {
+ Assert.Throws(() => default_brush.SetSigmaBellShape(-1));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_FocusTooBig()
+ {
+ Assert.Throws(() => default_brush.SetSigmaBellShape(1.01f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_ScaleTooSmall()
+ {
+ Assert.Throws(() => default_brush.SetSigmaBellShape(1, -1));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_ScaleTooBig()
+ {
+ Assert.Throws(() => default_brush.SetSigmaBellShape(1, 1.01f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 0f);
+ lgb.TranslateTransform(1, 1);
+ float[] elements = lgb.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(1, elements[4], 1);
+ Assert.Equal(1, elements[5], 1);
+
+ lgb.TranslateTransform(-1, -1);
+ // strangely lgb.Transform.IsIdentity is false
+ elements = lgb.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform_InvalidOrder()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(pt1, pt2, c1, c2);
+ Assert.Throws(() => lgb.TranslateTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Operations()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 45f);
+ Matrix clone = lgb.Transform.Clone();
+ Matrix mul = clone.Clone();
+
+ clone.Multiply(mul, MatrixOrder.Append);
+ lgb.MultiplyTransform(mul, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Multiply(mul, MatrixOrder.Prepend);
+ lgb.MultiplyTransform(mul, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Append);
+ lgb.RotateTransform(45, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Prepend);
+ lgb.RotateTransform(45, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Append);
+ lgb.ScaleTransform(0.25f, 2, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Prepend);
+ lgb.ScaleTransform(0.25f, 2, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Translate(10, 20, MatrixOrder.Append);
+ lgb.TranslateTransform(10, 20, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Translate(30, 40, MatrixOrder.Prepend);
+ lgb.TranslateTransform(30, 40, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Reset();
+ lgb.ResetTransform();
+ Assert.Equal(lgb.Transform, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Operations_OnScalableAngle()
+ {
+ LinearGradientBrush lgb = new LinearGradientBrush(rect, c1, c2, 360f, true);
+ Matrix clone = lgb.Transform.Clone();
+ Matrix mul = clone.Clone();
+ Matrix m = new Matrix();
+ m.Scale(2, 1);
+ m.Translate(rect.Width, rect.Height);
+ m.Rotate(30f);
+
+ clone.Multiply(mul, MatrixOrder.Append);
+ lgb.MultiplyTransform(mul, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Multiply(mul, MatrixOrder.Prepend);
+ lgb.MultiplyTransform(mul, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Append);
+ lgb.RotateTransform(45, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Prepend);
+ lgb.RotateTransform(45, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Append);
+ lgb.ScaleTransform(0.25f, 2, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Prepend);
+ lgb.ScaleTransform(0.25f, 2, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Translate(10, 20, MatrixOrder.Append);
+ lgb.TranslateTransform(10, 20, MatrixOrder.Append);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Translate(30, 40, MatrixOrder.Prepend);
+ lgb.TranslateTransform(30, 40, MatrixOrder.Prepend);
+ Assert.Equal(lgb.Transform, clone);
+
+ clone.Reset();
+ lgb.ResetTransform();
+ Assert.Equal(lgb.Transform, clone);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Rectangle_Angle_Scalable()
+ {
+ CheckMatrixForScalableAngle(new RectangleF(0, 0, 10, 10), 15, new float[] { 1.183013f, 0.3169873f, -0.3169873f, 1.183012f, 0.6698728f, -2.5f });
+
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 15, new float[] { 1.183012f, 0.176104f, -0.5705772f, 1.183012f, 34.77311f, -28.76387f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 75, new float[] { 0.3169872f, 0.6572293f, -2.129423f, 0.3169873f, 232.2269f, 8.763878f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 95, new float[] { -0.09442029f, 0.599571f, -1.942611f, -0.09442017f, 247.2034f, 48.05788f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 150, new float[] { -1.183013f, 0.3794515f, -1.229423f, -1.183013f, 268.2269f, 157.0972f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 215, new float[] { -1.140856f, -0.4437979f, 1.437905f, -1.140856f, 38.34229f, 215.2576f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 50), 300, new float[] { 0.6830127f, -0.6572294f, 2.129422f, 0.6830124f, -157.2269f, 76.23613f });
+
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 15, new float[] { 1.183012f, 0.5283121f, -0.1901924f, 1.183012f, 11.95002f, -64.33012f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 75, new float[] { 0.3169872f, 1.971688f, -0.7098077f, 0.3169872f, 147.05f, -55.66987f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 95, new float[] { -0.09442029f, 1.798713f, -0.6475369f, -0.09442022f, 169.499f, 12.84323f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 150, new float[] { -1.183013f, 1.138354f, -0.4098077f, -1.183013f, 219.05f, 209.3301f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 215, new float[] { -1.140856f, -1.331394f, 0.4793016f, -1.140856f, 95.85849f, 388.8701f });
+ CheckMatrixForScalableAngle(new RectangleF(30, 60, 90, 150), 300, new float[] { 0.6830127f, -1.971688f, 0.7098075f, 0.6830125f, -72.04998f, 190.6699f });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LinearColors_Null()
+ {
+ Assert.Throws(() => default_brush.LinearColors = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void InterpolationColors_Null()
+ {
+ Assert.Throws(() => default_brush.InterpolationColors = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Blend_Null()
+ {
+ Assert.Throws(() => default_brush.Blend = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ZeroWidthRectangle()
+ {
+ Rectangle r = new Rectangle(10, 10, 0, 10);
+ Assert.Equal(0, r.Width);
+ Assert.Throws(() => new LinearGradientBrush(r, Color.Red, Color.Blue, LinearGradientMode.Vertical));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ZeroHeightRectangleF()
+ {
+ RectangleF r = new RectangleF(10.0f, 10.0f, 10.0f, 0.0f);
+ Assert.Equal(0.0f, r.Height);
+ Assert.Throws(() => new LinearGradientBrush(r, Color.Red, Color.Blue, LinearGradientMode.Vertical));
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathDataTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathDataTest.cs
new file mode 100644
index 000000000000..7587fe289a1c
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathDataTest.cs
@@ -0,0 +1,89 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Drawing2D.PathData unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+
+ public class PathDataTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathData_Empty()
+ {
+ PathData data = new PathData();
+ Assert.Null(data.Points);
+ Assert.Null(data.Types);
+
+ data.Points = new PointF[0];
+ data.Types = new byte[0];
+ Assert.Equal(0, data.Points.Length);
+ Assert.Equal(0, data.Types.Length);
+
+ data.Points = null;
+ data.Types = null;
+ Assert.Null(data.Points);
+ Assert.Null(data.Types);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathData_LengthMismatch()
+ {
+ PathData data = new PathData();
+ data.Points = new PointF[2];
+ data.Types = new byte[1];
+ Assert.Equal(2, data.Points.Length);
+ Assert.Equal(1, data.Types.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathData_UnclonedProperties()
+ {
+ PathData data = new PathData();
+ data.Points = new PointF[1] { new PointF(1f, 1f) };
+ data.Types = new byte[1] { 1 };
+ Assert.Equal(1f, data.Points[0].X);
+ Assert.Equal(1f, data.Points[0].Y);
+ Assert.Equal(1, data.Types[0]);
+
+ data.Points[0] = new PointF(0f, 0f);
+ Assert.Equal(0f, data.Points[0].X);
+ Assert.Equal(0f, data.Points[0].Y);
+
+ data.Types[0] = 0;
+ Assert.Equal(0, data.Types[0]);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathGradientBrushTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathGradientBrushTest.cs
new file mode 100644
index 000000000000..fe2976fdbc4d
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/PathGradientBrushTest.cs
@@ -0,0 +1,919 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Drawing2D.PathGradientBrush unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+
+ public class PathGradientBrushTest
+ {
+
+ private Point[] pts_2i;
+ private PointF[] pts_2f;
+ private Matrix empty_matrix;
+
+ private void CheckDefaultRectangle(string message, RectangleF rect)
+ {
+ Assert.Equal(1f, rect.X);
+ Assert.Equal(2f, rect.Y);
+ Assert.Equal(19f, rect.Width);
+ Assert.Equal(28f, rect.Height);
+ }
+
+ private void CheckDefaults(PathGradientBrush pgb)
+ {
+ Assert.Equal(1, pgb.Blend.Factors.Length);
+ Assert.Equal(1f, pgb.Blend.Factors[0]);
+ Assert.Equal(1, pgb.Blend.Positions.Length);
+ Assert.Equal(0f, pgb.Blend.Positions[0]);
+ Assert.Equal(10.5f, pgb.CenterPoint.X);
+ Assert.Equal(16f, pgb.CenterPoint.Y);
+ Assert.True(pgb.FocusScales.IsEmpty);
+ Assert.Equal(1, pgb.InterpolationColors.Colors.Length);
+ Assert.Equal(0, pgb.InterpolationColors.Colors[0].ToArgb());
+ Assert.Equal(1, pgb.InterpolationColors.Positions.Length);
+ Assert.Equal(0f, pgb.InterpolationColors.Positions[0]);
+ CheckDefaultRectangle(String.Empty, pgb.Rectangle);
+ Assert.Equal(1, pgb.SurroundColors.Length);
+ Assert.Equal(-1, pgb.SurroundColors[0].ToArgb());
+ Assert.True(pgb.Transform.IsIdentity);
+ }
+
+ private void CheckPointsDefaults(PathGradientBrush pgb)
+ {
+ CheckDefaults(pgb);
+ Assert.Equal(-16777216, pgb.CenterColor.ToArgb());
+ }
+
+ private void CheckPathDefaults(PathGradientBrush pgb)
+ {
+ CheckDefaults(pgb);
+ Assert.Equal(-1, pgb.CenterColor.ToArgb());
+ }
+
+ public PathGradientBrushTest()
+ {
+ pts_2i = new Point[2] { new Point(1, 2), new Point(20, 30) };
+ pts_2f = new PointF[2] { new PointF(1, 2), new PointF(20, 30) };
+ empty_matrix = new Matrix();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_GraphicsPath_Null()
+ {
+ GraphicsPath gp = null;
+ Assert.Throws(() => new PathGradientBrush(gp));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_GraphicsPath_Empty()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ Assert.Throws(() => new PathGradientBrush(gp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_GraphicsPath_SinglePoint()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(new Point[1] { new Point(1, 1) });
+ // Special case - a line with a single point is valid
+ Assert.Throws(() => new PathGradientBrush(gp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Deskop & Core")]
+ public void Constructor_GraphicsPath_Line()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (PathGradientBrush pgb = new PathGradientBrush(gp))
+ {
+ CheckPathDefaults(pgb);
+ Assert.Equal(WrapMode.Clamp, pgb.WrapMode);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Null()
+ {
+ Point[] pts = null;
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_Empty()
+ {
+ Point[] pts = new Point[0];
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Point_One()
+ {
+ Point[] pts = new Point[1] { new Point(1, 1) };
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_Point_Two()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Clamp, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_Point_WrapMode_Clamp()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i, WrapMode.Clamp))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Clamp, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_Point_WrapMode_Tile()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i, WrapMode.Tile))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Tile, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & Core")]
+ public void Constructor_Point_WrapMode_TileFlipX()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i, WrapMode.TileFlipX))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipX, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & Core")]
+ public void Constructor_Point_WrapMode_TileFlipY()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i, WrapMode.TileFlipY))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipY, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconstent between Desktop & CoreFX")]
+ public void Constructor_Point_WrapMode_TileFlipXY()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2i, WrapMode.TileFlipXY))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipXY, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_Null()
+ {
+ PointF[] pts = null;
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_Empty()
+ {
+ PointF[] pts = new PointF[0];
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_PointF_One()
+ {
+ PointF[] pts = new PointF[1] { new PointF(1, 1) };
+ Assert.Throws(() => new PathGradientBrush(pts));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_PointF_Two()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Clamp, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void Constructor_PointF_WrapMode_Invalid()
+ {
+ Assert.Throws(() => new PathGradientBrush(pts_2f, (WrapMode)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void Constructor_PointF_WrapMode_Clamp()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Clamp, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_PointF_WrapMode_Tile()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Tile))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.Tile, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_PointF_WrapMode_TileFlipX()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipX))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipX, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_PointF_WrapMode_TileFlipY()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipY))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipY, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Inconsistent between Desktop & CoreFX")]
+ public void Constructor_PointF_WrapMode_TileFlipXY()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ CheckPointsDefaults(pgb);
+ Assert.Equal(WrapMode.TileFlipXY, pgb.WrapMode);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Blend()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ // change not accepted - but no exception is thrown
+ pgb.Blend.Factors = new float[0];
+ Assert.Equal(1, pgb.Blend.Factors.Length);
+ pgb.Blend.Factors = new float[2];
+ Assert.Equal(1, pgb.Blend.Factors.Length);
+
+ // change not accepted - but no exception is thrown
+ pgb.Blend.Positions = new float[0];
+ Assert.Equal(1, pgb.Blend.Positions.Length);
+ pgb.Blend.Positions = new float[2];
+ Assert.Equal(1, pgb.Blend.Positions.Length);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FocusScales()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ PointF fs = new PointF(Single.MaxValue, Single.MinValue);
+ pgb.FocusScales = fs;
+ Assert.Equal(Single.MaxValue, pgb.FocusScales.X);
+ Assert.Equal(Single.MinValue, pgb.FocusScales.Y);
+
+ fs.X = Single.NaN;
+ fs.Y = Single.NegativeInfinity;
+ pgb.FocusScales = fs;
+ Assert.Equal(Single.NaN, pgb.FocusScales.X);
+ Assert.Equal(Single.NegativeInfinity, pgb.FocusScales.Y);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CenterColor()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ pgb.CenterColor = Color.Black;
+ Assert.Equal(Color.Black.ToArgb(), pgb.CenterColor.ToArgb());
+ pgb.CenterColor = Color.Transparent;
+ Assert.Equal(Color.Transparent.ToArgb(), pgb.CenterColor.ToArgb());
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CenterPoint()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ PointF cp = new PointF(Single.MaxValue, Single.MinValue);
+ pgb.CenterPoint = cp;
+ Assert.Equal(Single.MaxValue, pgb.CenterPoint.X);
+ Assert.Equal(Single.MinValue, pgb.CenterPoint.Y);
+
+ cp.X = Single.NaN;
+ cp.Y = Single.NegativeInfinity;
+ pgb.CenterPoint = cp;
+ Assert.Equal(Single.NaN, pgb.CenterPoint.X);
+ Assert.Equal(Single.NegativeInfinity, pgb.CenterPoint.Y);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void InterpolationColors()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ // change not accepted - but no exception is thrown
+ pgb.InterpolationColors.Colors = new Color[0];
+ Assert.Equal(1, pgb.InterpolationColors.Colors.Length);
+ pgb.InterpolationColors.Colors = new Color[2];
+ Assert.Equal(1, pgb.InterpolationColors.Colors.Length);
+
+ // change not accepted - but no exception is thrown
+ pgb.InterpolationColors.Positions = new float[0];
+ Assert.Equal(1, pgb.InterpolationColors.Positions.Length);
+ pgb.InterpolationColors.Positions = new float[2];
+ Assert.Equal(1, pgb.InterpolationColors.Positions.Length);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rectangle()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ CheckDefaultRectangle("Original", pgb.Rectangle);
+ pgb.MultiplyTransform(new Matrix(2, 0, 0, 2, 2, 2));
+ CheckDefaultRectangle("Multiply", pgb.Rectangle);
+ pgb.ResetTransform();
+ CheckDefaultRectangle("Reset", pgb.Rectangle);
+ pgb.RotateTransform(90);
+ CheckDefaultRectangle("Rotate", pgb.Rectangle);
+ pgb.ScaleTransform(4, 0.25f);
+ CheckDefaultRectangle("Scale", pgb.Rectangle);
+ pgb.TranslateTransform(-10, -20);
+ CheckDefaultRectangle("Translate", pgb.Rectangle);
+
+ pgb.SetBlendTriangularShape(0.5f);
+ CheckDefaultRectangle("SetBlendTriangularShape", pgb.Rectangle);
+ pgb.SetSigmaBellShape(0.5f);
+ CheckDefaultRectangle("SetSigmaBellShape", pgb.Rectangle);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SurroundColors_Empty()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ Assert.Throws(() => pgb.SurroundColors = new Color[0]);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SurroundColors_2PointF()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.TileFlipXY))
+ {
+ // default values
+ Assert.Equal(1, pgb.SurroundColors.Length);
+ Assert.Equal(-1, pgb.SurroundColors[0].ToArgb());
+
+ // default can't be changed
+ pgb.SurroundColors[0] = Color.Gold;
+ Assert.Equal(-1, pgb.SurroundColors[0].ToArgb());
+
+ // 2 empty color isn't valid, change isn't accepted
+ pgb.SurroundColors = new Color[2];
+ Assert.Equal(1, pgb.SurroundColors.Length);
+
+ pgb.SurroundColors = new Color[2] { Color.Black, Color.White };
+ Assert.Equal(2, pgb.SurroundColors.Length);
+ Assert.Equal(-16777216, pgb.SurroundColors[0].ToArgb());
+ Assert.Equal(-1, pgb.SurroundColors[1].ToArgb());
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SurroundColors_3PointsF()
+ {
+ PointF[] points = new PointF[3] { new PointF(5, 50), new PointF(10, 100), new PointF(20, 75) };
+ using (PathGradientBrush pgb = new PathGradientBrush(points))
+ {
+ // 3 empty color isn't valid, change isn't accepted
+ pgb.SurroundColors = new Color[3] { Color.Empty, Color.Empty, Color.Empty };
+ Assert.Equal(1, pgb.SurroundColors.Length);
+
+ pgb.SurroundColors = new Color[3] { Color.Red, Color.Green, Color.Blue };
+ // change not accepted - but no exception is thrown
+ Assert.Equal(3, pgb.SurroundColors.Length);
+ Assert.Equal(-65536, pgb.SurroundColors[0].ToArgb());
+ Assert.Equal(-16744448, pgb.SurroundColors[1].ToArgb());
+ Assert.Equal(-16776961, pgb.SurroundColors[2].ToArgb());
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Null()
+ {
+ Assert.Throws(() => new PathGradientBrush(pts_2f, WrapMode.Clamp).Transform = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Empty()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.Transform = new Matrix();
+ Assert.True(pgb.Transform.IsIdentity);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_NonInvertible()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.Transform = new Matrix(123, 24, 82, 16, 47, 30));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WrapMode_All()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ foreach (WrapMode wm in Enum.GetValues(typeof(WrapMode)))
+ {
+ pgb.WrapMode = wm;
+ Assert.Equal(wm, pgb.WrapMode);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void WrapMode_Invalid()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.WrapMode = (WrapMode)Int32.MinValue);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void Clone()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (PathGradientBrush pgb = new PathGradientBrush(gp))
+ {
+ using (PathGradientBrush clone = (PathGradientBrush)pgb.Clone())
+ {
+ CheckPathDefaults(clone);
+ Assert.Equal(WrapMode.Clamp, clone.WrapMode);
+ }
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform1_Null()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.MultiplyTransform(null));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform2_Null()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.MultiplyTransform(null, MatrixOrder.Append));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform2_Invalid()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.MultiplyTransform(empty_matrix, (MatrixOrder)Int32.MinValue);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform_NonInvertible()
+ {
+ using (Matrix noninvertible = new Matrix(123, 24, 82, 16, 47, 30))
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.MultiplyTransform(noninvertible));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ResetTransform()
+ {
+ using (Matrix m = new Matrix(2, 0, 0, 2, 10, -10))
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.Transform = m;
+ Assert.False(pgb.Transform.IsIdentity);
+ pgb.ResetTransform();
+ Assert.True(pgb.Transform.IsIdentity);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.RotateTransform(90);
+ float[] elements = pgb.Transform.Elements;
+ Assert.Equal(0, elements[0], 1);
+ Assert.Equal(1, elements[1], 1);
+ Assert.Equal(-1, elements[2], 1);
+ Assert.Equal(0, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ pgb.RotateTransform(270);
+ Assert.True(pgb.Transform.IsIdentity);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform_InvalidOrder()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.RotateTransform(720, (MatrixOrder)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.ScaleTransform(2, 4);
+ float[] elements = pgb.Transform.Elements;
+ Assert.Equal(2, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(4, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ pgb.ScaleTransform(0.5f, 0.25f);
+ Assert.True(pgb.Transform.IsIdentity);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_MaxMin()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.ScaleTransform(Single.MaxValue, Single.MinValue);
+ float[] elements = pgb.Transform.Elements;
+ Assert.Equal(Single.MaxValue, elements[0]);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(Single.MinValue, elements[3]);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_InvalidOrder()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.ScaleTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_Focus()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ // max valid
+ pgb.SetBlendTriangularShape(1);
+ Assert.True(pgb.Transform.IsIdentity);
+ // min valid
+ pgb.SetBlendTriangularShape(0);
+ Assert.True(pgb.Transform.IsIdentity);
+ // middle
+ pgb.SetBlendTriangularShape(0.5f);
+ Assert.True(pgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_Scale()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ // max valid
+ pgb.SetBlendTriangularShape(0, 1);
+ Assert.True(pgb.Transform.IsIdentity);
+ // min valid
+ pgb.SetBlendTriangularShape(1, 0);
+ Assert.True(pgb.Transform.IsIdentity);
+ // middle
+ pgb.SetBlendTriangularShape(0.5f, 0.5f);
+ Assert.True(pgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_FocusTooSmall()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetBlendTriangularShape(-1));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_FocusTooBig()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetBlendTriangularShape(1.01f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_ScaleTooSmall()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetBlendTriangularShape(1, -1));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetBlendTriangularShape_ScaleTooBig()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetBlendTriangularShape(1, 1.01f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_Focus()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ // max valid
+ pgb.SetSigmaBellShape(1);
+ Assert.True(pgb.Transform.IsIdentity);
+ // min valid
+ pgb.SetSigmaBellShape(0);
+ Assert.True(pgb.Transform.IsIdentity);
+ // middle
+ pgb.SetSigmaBellShape(0.5f);
+ Assert.True(pgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_Scale()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ // max valid
+ pgb.SetSigmaBellShape(0, 1);
+ Assert.True(pgb.Transform.IsIdentity);
+ // min valid
+ pgb.SetSigmaBellShape(1, 0);
+ Assert.True(pgb.Transform.IsIdentity);
+ // middle
+ pgb.SetSigmaBellShape(0.5f, 0.5f);
+ Assert.True(pgb.Transform.IsIdentity);
+ // no impact on matrix
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_FocusTooSmall()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetSigmaBellShape(-1));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_FocusTooBig()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetSigmaBellShape(1.01f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_ScaleTooSmall()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetSigmaBellShape(1, -1));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetSigmaBellShape_ScaleTooBig()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.SetSigmaBellShape(1, 1.01f));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ pgb.TranslateTransform(1, 1);
+ float[] elements = pgb.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(1, elements[4], 1);
+ Assert.Equal(1, elements[5], 1);
+
+ pgb.TranslateTransform(-1, -1);
+ // strangely lgb.Transform.IsIdentity is false
+ elements = pgb.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform_InvalidOrder()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Assert.Throws(() => pgb.TranslateTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Operations()
+ {
+ using (PathGradientBrush pgb = new PathGradientBrush(pts_2f, WrapMode.Clamp))
+ {
+ Matrix clone = pgb.Transform.Clone();
+ Matrix mul = clone.Clone();
+
+ clone.Multiply(mul, MatrixOrder.Append);
+ pgb.MultiplyTransform(mul, MatrixOrder.Append);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Multiply(mul, MatrixOrder.Prepend);
+ pgb.MultiplyTransform(mul, MatrixOrder.Prepend);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Append);
+ pgb.RotateTransform(45, MatrixOrder.Append);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Prepend);
+ pgb.RotateTransform(45, MatrixOrder.Prepend);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Append);
+ pgb.ScaleTransform(0.25f, 2, MatrixOrder.Append);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Prepend);
+ pgb.ScaleTransform(0.25f, 2, MatrixOrder.Prepend);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Translate(10, 20, MatrixOrder.Append);
+ pgb.TranslateTransform(10, 20, MatrixOrder.Append);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Translate(30, 40, MatrixOrder.Prepend);
+ pgb.TranslateTransform(30, 40, MatrixOrder.Prepend);
+ Assert.Equal(pgb.Transform, clone);
+
+ clone.Reset();
+ pgb.ResetTransform();
+ Assert.Equal(pgb.Transform, clone);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Blend_Null()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (PathGradientBrush pgb = new PathGradientBrush(gp))
+ {
+ Assert.Throws(() => pgb.Blend = null);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void InterpolationColors_Null()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (PathGradientBrush pgb = new PathGradientBrush(gp))
+ {
+ Assert.Throws(() => pgb.InterpolationColors = null);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SurroundColors_Null()
+ {
+ using (GraphicsPath gp = new GraphicsPath())
+ {
+ gp.AddLines(pts_2f);
+ using (PathGradientBrush pgb = new PathGradientBrush(gp))
+ {
+ Assert.Throws(() => pgb.SurroundColors = null);
+ }
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestBlend.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestBlend.cs
new file mode 100644
index 000000000000..28b8bcbe9906
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestBlend.cs
@@ -0,0 +1,77 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Tests for System.Drawing.Drawing2D.Blend.cs
+//
+// Author:
+// Ravindra (rkumar@novell.com)
+//
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Xunit;
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+ public class BlendTest
+ {
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestConstructors()
+ {
+ Blend blend0 = new Blend();
+
+ Assert.Equal(1, blend0.Factors.Length);
+ Assert.Equal(1, blend0.Positions.Length);
+
+ Blend blend1 = new Blend(1);
+
+ Assert.Equal(1, blend1.Factors.Length);
+ Assert.Equal(1, blend1.Positions.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestProperties()
+ {
+ Blend blend0 = new Blend();
+
+ Assert.Equal(0, blend0.Factors[0]);
+ Assert.Equal(0, blend0.Positions[0]);
+
+ Blend blend1 = new Blend(1);
+ float[] positions = { 0.0F, 0.5F, 1.0F };
+ float[] factors = { 0.0F, 0.5F, 1.0F };
+ blend1.Factors = factors;
+ blend1.Positions = positions;
+
+ Assert.Equal(factors[0], blend1.Factors[0]);
+ Assert.Equal(factors[1], blend1.Factors[1]);
+ Assert.Equal(factors[2], blend1.Factors[2]);
+ Assert.Equal(positions[0], blend1.Positions[0]);
+ Assert.Equal(positions[1], blend1.Positions[1]);
+ Assert.Equal(positions[2], blend1.Positions[2]);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestColorBlend.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestColorBlend.cs
new file mode 100644
index 000000000000..2c3674e25dd6
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestColorBlend.cs
@@ -0,0 +1,113 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Tests for System.Drawing.Drawing2D.ColorBlend.cs
+//
+// Authors:
+// Ravindra (rkumar@novell.com)
+// Sebastien Pouliot
+//
+// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Xunit;
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+ public class ColorBlendTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestConstructors()
+ {
+ ColorBlend cb1 = new ColorBlend(1);
+ Assert.Equal(1, cb1.Colors.Length);
+ Assert.Equal(1, cb1.Positions.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestProperties()
+ {
+ ColorBlend cb1 = new ColorBlend(1);
+ float[] positions = { 0.0F, 0.5F, 1.0F };
+ Color[] colors = { Color.Red, Color.White, Color.Black };
+ cb1.Colors = colors;
+ cb1.Positions = positions;
+
+ // size match
+ Assert.Equal(colors[0], cb1.Colors[0]);
+ Assert.Equal(colors[1], cb1.Colors[1]);
+ Assert.Equal(colors[2], cb1.Colors[2]);
+ Assert.Equal(positions[0], cb1.Positions[0]);
+ Assert.Equal(positions[1], cb1.Positions[1]);
+ Assert.Equal(positions[2], cb1.Positions[2]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorBlend_Empty()
+ {
+ ColorBlend cb = new ColorBlend();
+ Assert.Equal(1, cb.Colors.Length);
+ Assert.True(cb.Colors[0].IsEmpty);
+ Assert.Equal(1, cb.Positions.Length);
+ Assert.Equal(0f, cb.Positions[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorBlend_Zero()
+ {
+ ColorBlend cb = new ColorBlend(0);
+ Assert.Equal(0, cb.Colors.Length);
+ Assert.Equal(0, cb.Positions.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MismatchSizes()
+ {
+ ColorBlend cb = new ColorBlend();
+
+ cb.Colors = new Color[16];
+ Assert.Equal(16, cb.Colors.Length);
+
+ cb.Positions = new float[1];
+ Assert.Equal(1, cb.Positions.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorBlend_Negative()
+ {
+ Assert.Throws(() => new ColorBlend(-1));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorBlend_Lots()
+ {
+ ColorBlend cb = new ColorBlend(1000);
+ Assert.Equal(1000, cb.Colors.Length);
+ Assert.Equal(1000, cb.Positions.Length);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestHatchBrush.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestHatchBrush.cs
new file mode 100644
index 000000000000..8dcae32cec1f
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestHatchBrush.cs
@@ -0,0 +1,633 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Drawing2D.TestHatchBrush.cs
+//
+// Author:
+// Ravindra (rkumar@novell.com)
+//
+// Copyright (C) 2004,2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+ public class HatchBrushTest
+ {
+ Graphics gr;
+ Bitmap bmp;
+ Font font;
+ Color bgColor; // background color
+ Color fgColor; // foreground color
+ int currentTop; // the location for next drawing operation
+ int spacing; // space between two consecutive drawing operations
+ int fontSize; // text size
+ int textStart; // text starting location
+ int lineStart; // line starting location
+ int length; // length of the line
+ int penWidth; // width of the Pen used to draw lines
+
+
+ public HatchBrushTest()
+ {
+ fontSize = 16;
+ textStart = 10;
+ lineStart = 200;
+ length = 400;
+ penWidth = 50;
+ currentTop = 0;
+ spacing = 50;
+
+ bgColor = Color.Yellow;
+ fgColor = Color.Red;
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestProperties()
+ {
+ HatchBrush hbr = new HatchBrush(HatchStyle.SolidDiamond, fgColor);
+
+ Assert.Equal(hbr.HatchStyle, HatchStyle.SolidDiamond);
+ Assert.Equal(hbr.ForegroundColor.ToArgb(), fgColor.ToArgb());
+ Assert.Equal(hbr.BackgroundColor.ToArgb(), Color.Black.ToArgb());
+
+ hbr = new HatchBrush(HatchStyle.Cross, fgColor, bgColor);
+
+ Assert.Equal(hbr.HatchStyle, HatchStyle.Cross);
+ Assert.Equal(hbr.ForegroundColor.ToArgb(), fgColor.ToArgb());
+ Assert.Equal(hbr.BackgroundColor.ToArgb(), bgColor.ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestClone()
+ {
+ HatchBrush hbr = new HatchBrush(HatchStyle.Cross, fgColor, bgColor);
+
+ HatchBrush clone = (HatchBrush)hbr.Clone();
+
+ Assert.Equal(hbr.HatchStyle, clone.HatchStyle);
+ Assert.Equal(hbr.ForegroundColor, clone.ForegroundColor);
+ Assert.Equal(hbr.BackgroundColor, clone.BackgroundColor);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestDrawing()
+ {
+ // create a bitmap with big enough dimensions
+ // to accomodate all the tests
+ bmp = new Bitmap(700, 6000); // width, height
+ gr = Graphics.FromImage(bmp);
+ try
+ {
+ font = new Font(new FontFamily("Arial"), fontSize);
+ }
+ catch (ArgumentException)
+ {
+ Assert.True(false, "Arial FontFamily couldn't be found");
+ }
+
+ // make the background white
+ gr.Clear(Color.White);
+
+ // draw figures using hatch brush constructed
+ // using different constructors
+ Constructors();
+
+ // draw figures using different hatchstyles
+ HatchStyles();
+
+ // save the drawing
+ string file = "TestHatchBrush" + getOutSufix() + ".png";
+ bmp.Save(file, ImageFormat.Png);
+ File.Delete(file);
+ }
+
+ private void Constructors()
+ {
+ int top = currentTop;
+ SolidBrush br = new SolidBrush(Color.Black);
+
+ top += spacing;
+
+ gr.DrawString("Test Constructors", font, br, textStart, top);
+
+ // #1
+ top += spacing;
+ gr.DrawString("Test #1 Horizontal, BackgroundColor=Black, ForegroundColor=White", font, br, textStart, top);
+
+ top += spacing;
+ Pen pen = new Pen(new HatchBrush(HatchStyle.Horizontal, Color.White), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #2
+ top += spacing;
+ gr.DrawString("Test #2 Vertical, BackgroundColor=Blue, ForegroundColor=Red", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Vertical, Color.Red, Color.Blue), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ currentTop = top;
+ }
+
+ private void HatchStyles()
+ {
+ int top = currentTop;
+ HatchBrush hbr;
+ Pen pen;
+ SolidBrush br = new SolidBrush(Color.Black);
+
+ top += spacing;
+
+ gr.DrawString("Test HatchStyles", font, br, textStart, top);
+
+ // #1
+ top += spacing;
+ gr.DrawString("Test #1 Horizontal", font, br, textStart, top);
+
+ top += spacing;
+ hbr = new HatchBrush(HatchStyle.Horizontal, fgColor, bgColor);
+ pen = new Pen(hbr, penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #2
+ top += spacing;
+ gr.DrawString("Test #2 Min", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Min, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #3
+ top += spacing;
+ gr.DrawString("Test #3 DarkHorizontal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DarkHorizontal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #4
+ top += spacing;
+ gr.DrawString("Test #4 LightHorizontal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LightHorizontal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #5
+ top += spacing;
+ gr.DrawString("Test #5 NarrowHorizontal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.NarrowHorizontal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #6
+ top += spacing;
+ gr.DrawString("Test #6 Vertical", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Vertical, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #7
+ top += spacing;
+ gr.DrawString("Test #7 DarkVertical", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DarkVertical, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #8
+ top += spacing;
+ gr.DrawString("Test #8 LightVertical", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LightVertical, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #9
+ top += spacing;
+ gr.DrawString("Test #9 NarrowVertical", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.NarrowVertical, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #10
+ top += spacing;
+ gr.DrawString("Test #10 Cross", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Cross, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #11
+ top += spacing;
+ gr.DrawString("Test #11 LargeGrid", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LargeGrid, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #12
+ top += spacing;
+ gr.DrawString("Test #12 SmallGrid", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.SmallGrid, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #13
+ top += spacing;
+ gr.DrawString("Test #13 DottedGrid", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DottedGrid, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #14
+ top += spacing;
+ gr.DrawString("Test #14 DiagonalCross", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DiagonalCross, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #15
+ top += spacing;
+ gr.DrawString("Test #15 BackwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.BackwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #16
+ top += spacing;
+ gr.DrawString("Test #16 ForwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.ForwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #17
+ top += spacing;
+ gr.DrawString("Test #17 LightDownwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LightDownwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #18
+ top += spacing;
+ gr.DrawString("Test #18 DarkDownwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DarkDownwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #19
+ top += spacing;
+ gr.DrawString("Test #19 WideDownwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.WideDownwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #20
+ top += spacing;
+ gr.DrawString("Test #20 LightUpwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LightUpwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #21
+ top += spacing;
+ gr.DrawString("Test #21 DarkUpwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DarkUpwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #22
+ top += spacing;
+ gr.DrawString("Test #22 WideUpwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.WideUpwardDiagonal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #23
+ top += spacing;
+ gr.DrawString("Test #23 DashedHorizontal", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DashedHorizontal, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #24
+ top += spacing;
+ gr.DrawString("Test #24 DashedVertical", font, br, textStart, top);
+
+ top += spacing;
+ hbr = new HatchBrush(HatchStyle.DashedVertical, fgColor, bgColor);
+ gr.FillRectangle(hbr, lineStart, top, length, penWidth);
+
+ // #25
+ top += spacing;
+ gr.DrawString("Test #25 DashedDownwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ hbr = new HatchBrush(HatchStyle.DashedDownwardDiagonal, fgColor, bgColor);
+ gr.FillRectangle(hbr, lineStart, top, length, penWidth);
+
+ // #26
+ top += spacing;
+ gr.DrawString("Test #26 DashedUpwardDiagonal", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.DashedUpwardDiagonal, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #27
+ top += spacing;
+ gr.DrawString("Test #27 05Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent05, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #28
+ top += spacing;
+ gr.DrawString("Test #28 10Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent10, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #29
+ top += spacing;
+ gr.DrawString("Test #29 20Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent20, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #30
+ top += spacing;
+ gr.DrawString("Test #30 25Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent25, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #31
+ top += spacing;
+ gr.DrawString("Test #31 30Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent30, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #32
+ top += spacing;
+ gr.DrawString("Test #32 40Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent40, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #33
+ top += spacing;
+ gr.DrawString("Test #33 50Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent50, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #34
+ top += spacing;
+ gr.DrawString("Test #34 60Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent60, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #35
+ top += spacing;
+ gr.DrawString("Test #35 70Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent70, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #36
+ top += spacing;
+ gr.DrawString("Test #36 75Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent75, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #37
+ top += spacing;
+ gr.DrawString("Test #37 80Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent80, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #38
+ top += spacing;
+ gr.DrawString("Test #38 90Percent", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Percent90, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #39
+ top += spacing;
+ gr.DrawString("Test #39 SmallConfetti", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.SmallConfetti, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #40
+ top += spacing;
+ gr.DrawString("Test #40 LargeConfetti", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.LargeConfetti, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #41
+ top += spacing;
+ gr.DrawString("Test #41 ZigZag", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.ZigZag, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #42
+ top += spacing;
+ gr.DrawString("Test #42 Wave", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Wave, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #43
+ top += spacing;
+ gr.DrawString("Test #43 HorizontalBrick", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.HorizontalBrick, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #44
+ top += spacing;
+ gr.DrawString("Test #44 DiagonalBrick", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.DiagonalBrick, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #45
+ top += spacing;
+ gr.DrawString("Test #45 Weave", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Weave, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #46
+ top += spacing;
+ gr.DrawString("Test #46 Plaid", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Plaid, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #47
+ top += spacing;
+ gr.DrawString("Test #47 Divot", font, br, textStart, top);
+
+ top += spacing;
+ pen = new Pen(new HatchBrush(HatchStyle.Divot, fgColor, bgColor), penWidth);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #48
+ top += spacing;
+ gr.DrawString("Test #48 SmallCheckerBoard", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.SmallCheckerBoard, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #49
+ top += spacing;
+ gr.DrawString("Test #49 LargeCheckerBoard", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.LargeCheckerBoard, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #50
+ top += spacing;
+ gr.DrawString("Test #50 OutlinedDiamond", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.OutlinedDiamond, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #51
+ top += spacing;
+ gr.DrawString("Test #51 SolidDiamond", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.SolidDiamond, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #52
+ top += spacing;
+ gr.DrawString("Test #52 DottedDiamond", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.DottedDiamond, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #53
+ top += spacing;
+ gr.DrawString("Test #53 Shingle", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Shingle, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #54
+ top += spacing;
+ gr.DrawString("Test #54 Trellis", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Trellis, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ // #55
+ top += spacing;
+ gr.DrawString("Test #55 Sphere", font, br, textStart, top);
+
+ top += spacing;
+ pen.Brush = new HatchBrush(HatchStyle.Sphere, fgColor, bgColor);
+ gr.DrawLine(pen, lineStart, top, lineStart + length, top);
+
+ currentTop = top;
+ }
+
+ internal string getOutSufix()
+ {
+ string s;
+
+ int p = (int)Environment.OSVersion.Platform;
+ if ((p == 4) || (p == 128) || (p == 6))
+ s = "-unix";
+ else
+ s = "-windows";
+
+ if (Type.GetType("Mono.Runtime", false) == null)
+ s += "-msnet";
+ else
+ s += "-mono";
+
+ return s;
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestMatrix.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestMatrix.cs
new file mode 100644
index 000000000000..de948378d9f7
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Drawing2D/TestMatrix.cs
@@ -0,0 +1,651 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Tests for System.Drawing.Drawing2D.Matrix.cs
+//
+// Authors:
+// Jordi Mas i Hernandez
+// Sebastien Pouliot
+//
+// Copyright (C) 2005-2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Xunit;
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Drawing.Drawing2D
+{
+ public class MatrixTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Default()
+ {
+ Matrix matrix = new Matrix();
+ Assert.Equal(6, matrix.Elements.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_SixFloats()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ Assert.Equal(6, matrix.Elements.Length);
+ Assert.Equal(10, matrix.Elements[0]);
+ Assert.Equal(20, matrix.Elements[1]);
+ Assert.Equal(30, matrix.Elements[2]);
+ Assert.Equal(40, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Float()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ Assert.Equal(6, matrix.Elements.Length);
+ Assert.Equal(10, matrix.Elements[0]);
+ Assert.Equal(20, matrix.Elements[1]);
+ Assert.Equal(30, matrix.Elements[2]);
+ Assert.Equal(40, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Int_Null()
+ {
+ Assert.Throws(() => new Matrix(default(Rectangle), null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Int_Empty()
+ {
+ Assert.Throws(() => new Matrix(default(Rectangle), new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Int_4Point()
+ {
+ Assert.Throws(() => new Matrix(default(Rectangle), new Point[4]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Rect_Point()
+ {
+ Rectangle r = new Rectangle(100, 200, 300, 400);
+ Matrix m = new Matrix(r, new Point[3] { new Point(10, 20), new Point(30, 40), new Point(50, 60) });
+ float[] elements = m.Elements;
+ Assert.Equal(0.06666666, elements[0], 5);
+ Assert.Equal(0.06666666, elements[1], 5);
+ Assert.Equal(0.09999999, elements[2], 5);
+ Assert.Equal(0.09999999, elements[3], 5);
+ Assert.Equal(-16.6666679, elements[4], 5);
+ Assert.Equal(-6.666667, elements[5], 5);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Float_Null()
+ {
+ Assert.Throws(() => new Matrix(default(RectangleF), null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Float_Empty()
+ {
+ Assert.Throws(() => new Matrix(default(RectangleF), new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Float_2PointF()
+ {
+ Assert.Throws(() => new Matrix(default(RectangleF), new PointF[2]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_RectF_PointF()
+ {
+ RectangleF r = new RectangleF(100, 200, 300, 400);
+ Matrix m = new Matrix(r, new PointF[3] { new PointF(10, 20), new PointF(30, 40), new PointF(50, 60) });
+ float[] elements = m.Elements;
+ Assert.Equal(0.06666666, elements[0], 5);
+ Assert.Equal(0.06666666, elements[1], 5);
+ Assert.Equal(0.09999999, elements[2], 5);
+ Assert.Equal(0.09999999, elements[3], 5);
+ Assert.Equal(-16.6666679, elements[4], 5);
+ Assert.Equal(-6.666667, elements[5], 5);
+ }
+
+ // Properties
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Invertible()
+ {
+ Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30);
+ Assert.Equal(false, matrix.IsInvertible);
+
+ matrix = new Matrix(156, 46, 0, 0, 106, 19);
+ Assert.Equal(false, matrix.IsInvertible);
+
+ matrix = new Matrix(146, 66, 158, 104, 42, 150);
+ Assert.Equal(true, matrix.IsInvertible);
+
+ matrix = new Matrix(119, 140, 145, 74, 102, 58);
+ Assert.Equal(true, matrix.IsInvertible);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsIdentity()
+ {
+ Matrix identity = new Matrix();
+ Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30);
+ Assert.Equal(false, matrix.IsIdentity);
+ Assert.True(!identity.Equals(matrix));
+
+ matrix = new Matrix(1, 0, 0, 1, 0, 0);
+ Assert.Equal(true, matrix.IsIdentity);
+ Assert.True(identity.Equals(matrix));
+
+ // so what's the required precision ?
+
+ matrix = new Matrix(1.1f, 0.1f, -0.1f, 0.9f, 0, 0);
+ Assert.True(!matrix.IsIdentity);
+ Assert.True(!identity.Equals(matrix));
+
+ matrix = new Matrix(1.01f, 0.01f, -0.01f, 0.99f, 0, 0);
+ Assert.True(!matrix.IsIdentity);
+ Assert.True(!identity.Equals(matrix));
+
+ matrix = new Matrix(1.001f, 0.001f, -0.001f, 0.999f, 0, 0);
+ Assert.True(!matrix.IsIdentity);
+ Assert.True(!identity.Equals(matrix));
+
+ matrix = new Matrix(1.0001f, 0.0001f, -0.0001f, 0.9999f, 0, 0);
+ Assert.True(matrix.IsIdentity);
+ // note: NOT equal
+ Assert.True(!identity.Equals(matrix));
+
+ matrix = new Matrix(1.0009f, 0.0009f, -0.0009f, 0.99995f, 0, 0);
+ Assert.True(!matrix.IsIdentity);
+ Assert.True(!identity.Equals(matrix));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOffsetX()
+ {
+ Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30);
+ Assert.Equal(47, matrix.OffsetX);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsOffsetY()
+ {
+ Matrix matrix = new Matrix(123, 24, 82, 16, 47, 30);
+ Assert.Equal(30, matrix.OffsetY);
+ }
+
+ // Elements Property is checked implicity in other test
+
+ //
+ // Methods
+ //
+
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone()
+ {
+ Matrix matsrc = new Matrix(10, 20, 30, 40, 50, 60);
+ Matrix matrix = matsrc.Clone();
+
+ Assert.Equal(6, matrix.Elements.Length);
+ Assert.Equal(10, matrix.Elements[0]);
+ Assert.Equal(20, matrix.Elements[1]);
+ Assert.Equal(30, matrix.Elements[2]);
+ Assert.Equal(40, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void HashCode()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ Matrix clone = matrix.Clone();
+ Assert.True(matrix.GetHashCode() != clone.GetHashCode());
+
+ Matrix matrix2 = new Matrix(10, 20, 30, 40, 50, 60);
+ Assert.True(matrix.GetHashCode() != matrix2.GetHashCode());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Reset()
+ {
+ Matrix matrix = new Matrix(51, 52, 53, 54, 55, 56);
+ matrix.Reset();
+
+ Assert.Equal(6, matrix.Elements.Length);
+ Assert.Equal(1, matrix.Elements[0]);
+ Assert.Equal(0, matrix.Elements[1]);
+ Assert.Equal(0, matrix.Elements[2]);
+ Assert.Equal(1, matrix.Elements[3]);
+ Assert.Equal(0, matrix.Elements[4]);
+ Assert.Equal(0, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rotate()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Rotate(180);
+
+ Assert.Equal(-10.0f, matrix.Elements[0], 4);
+ Assert.Equal(-20, matrix.Elements[1], 4);
+ Assert.Equal(-30.0000019f, matrix.Elements[2], 4);
+ Assert.Equal(-40.0000038f, matrix.Elements[3], 4);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rotate_45_135()
+ {
+ Matrix matrix = new Matrix();
+ Assert.True(matrix.IsIdentity);
+
+ matrix.Rotate(45);
+ Assert.True(!matrix.IsIdentity);
+ float[] elements = matrix.Elements;
+ Assert.Equal(0.707106769f, elements[0], 4);
+ Assert.Equal(0.707106769f, elements[1], 4);
+ Assert.Equal(-0.707106829f, elements[2], 4);
+ Assert.Equal(0.707106769f, elements[3], 4);
+ Assert.Equal(0, elements[4], 3);
+ Assert.Equal(0, elements[5], 3);
+
+ matrix.Rotate(135);
+ Assert.True(!matrix.IsIdentity);
+ elements = matrix.Elements;
+ Assert.Equal(-1, elements[0], 4);
+ Assert.Equal(0, elements[1], 4);
+ Assert.Equal(0, elements[2], 4);
+ Assert.Equal(-1, elements[3], 4);
+ Assert.Equal(0, elements[4]);
+ Assert.Equal(0, elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rotate_90_270_Matrix()
+ {
+ Matrix matrix = new Matrix();
+ Assert.True(matrix.IsIdentity);
+
+ matrix.Rotate(90);
+ Assert.True(!matrix.IsIdentity);
+ float[] elements = matrix.Elements;
+ Assert.Equal(0, elements[0], 4);
+ Assert.Equal(1, elements[1], 4);
+ Assert.Equal(-1, elements[2], 4);
+ Assert.Equal(0, elements[3], 4);
+ Assert.Equal(0, elements[4]);
+ Assert.Equal(0, elements[5]);
+
+ matrix.Rotate(270);
+ // this isn't a perfect 1, 0, 0, 1, 0, 0 matrix - but close enough
+ Assert.True(matrix.IsIdentity);
+ Assert.True(!new Matrix().Equals(matrix));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rotate_InvalidOrder()
+ {
+ Assert.Throws(() => new Matrix().Rotate(180, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateAt()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.RotateAt(180, new PointF(10, 10));
+
+ Assert.Equal(-10, matrix.Elements[0], 2);
+ Assert.Equal(-20, matrix.Elements[1], 2);
+ Assert.Equal(-30, matrix.Elements[2], 2);
+ Assert.Equal(-40, matrix.Elements[3], 2);
+ Assert.Equal(850, matrix.Elements[4], 2);
+ Assert.Equal(1260, matrix.Elements[5], 2);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateAt_InvalidOrder()
+ {
+ Assert.Throws(() => new Matrix().RotateAt(180, new PointF(10, 10), (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply_Null()
+ {
+ Assert.Throws(() => new Matrix(10, 20, 30, 40, 50, 60).Multiply(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Multiply(new Matrix(10, 20, 30, 40, 50, 60));
+
+ Assert.Equal(700, matrix.Elements[0]);
+ Assert.Equal(1000, matrix.Elements[1]);
+ Assert.Equal(1500, matrix.Elements[2]);
+ Assert.Equal(2200, matrix.Elements[3]);
+ Assert.Equal(2350, matrix.Elements[4]);
+ Assert.Equal(3460, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply_Null_Order()
+ {
+ Assert.Throws(() => new Matrix(10, 20, 30, 40, 50, 60).Multiply(null, MatrixOrder.Append));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply_Append()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Multiply(new Matrix(10, 20, 30, 40, 50, 60), MatrixOrder.Append);
+
+ Assert.Equal(700, matrix.Elements[0]);
+ Assert.Equal(1000, matrix.Elements[1]);
+ Assert.Equal(1500, matrix.Elements[2]);
+ Assert.Equal(2200, matrix.Elements[3]);
+ Assert.Equal(2350, matrix.Elements[4]);
+ Assert.Equal(3460, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply_Prepend()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Multiply(new Matrix(10, 20, 30, 40, 50, 60), MatrixOrder.Prepend);
+
+ Assert.Equal(700, matrix.Elements[0]);
+ Assert.Equal(1000, matrix.Elements[1]);
+ Assert.Equal(1500, matrix.Elements[2]);
+ Assert.Equal(2200, matrix.Elements[3]);
+ Assert.Equal(2350, matrix.Elements[4]);
+ Assert.Equal(3460, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Multiply_InvalidOrder()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ Assert.Throws(() => matrix.Multiply(new Matrix(10, 20, 30, 40, 50, 60), (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Equals()
+ {
+ Matrix mat1 = new Matrix(10, 20, 30, 40, 50, 60);
+ Matrix mat2 = new Matrix(10, 20, 30, 40, 50, 60);
+ Matrix mat3 = new Matrix(10, 20, 30, 40, 50, 10);
+
+ Assert.Equal(true, mat1.Equals(mat2));
+ Assert.Equal(false, mat2.Equals(mat3));
+ Assert.Equal(false, mat1.Equals(mat3));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Invert()
+ {
+ Matrix matrix = new Matrix(1, 2, 3, 4, 5, 6);
+ matrix.Invert();
+
+ Assert.Equal(-2, matrix.Elements[0]);
+ Assert.Equal(1, matrix.Elements[1]);
+ Assert.Equal(1.5, matrix.Elements[2]);
+ Assert.Equal(-0.5, matrix.Elements[3]);
+ Assert.Equal(1, matrix.Elements[4]);
+ Assert.Equal(-2, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Invert_Translation()
+ {
+ Matrix matrix = new Matrix(1, 0, 0, 1, 8, 8);
+ matrix.Invert();
+
+ float[] elements = matrix.Elements;
+ Assert.Equal(1, elements[0]);
+ Assert.Equal(0, elements[1]);
+ Assert.Equal(0, elements[2]);
+ Assert.Equal(1, elements[3]);
+ Assert.Equal(-8, elements[4]);
+ Assert.Equal(-8, elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Invert_Identity()
+ {
+ Matrix matrix = new Matrix();
+ Assert.True(matrix.IsIdentity);
+ Assert.True(matrix.IsInvertible);
+ matrix.Invert();
+ Assert.True(matrix.IsIdentity);
+ Assert.True(matrix.IsInvertible);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Scale()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Scale(2, 4);
+
+ Assert.Equal(20, matrix.Elements[0]);
+ Assert.Equal(40, matrix.Elements[1]);
+ Assert.Equal(120, matrix.Elements[2]);
+ Assert.Equal(160, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+
+ matrix.Scale(0.5f, 0.25f);
+
+ Assert.Equal(10, matrix.Elements[0]);
+ Assert.Equal(20, matrix.Elements[1]);
+ Assert.Equal(30, matrix.Elements[2]);
+ Assert.Equal(40, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Scale_Negative()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Scale(-2, -4);
+
+ Assert.Equal(-20, matrix.Elements[0]);
+ Assert.Equal(-40, matrix.Elements[1]);
+ Assert.Equal(-120, matrix.Elements[2]);
+ Assert.Equal(-160, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Scale_InvalidOrder()
+ {
+ Assert.Throws(() => new Matrix().Scale(2, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Shear()
+ {
+ Matrix matrix = new Matrix(10, 20, 30, 40, 50, 60);
+ matrix.Shear(2, 4);
+
+ Assert.Equal(130, matrix.Elements[0]);
+ Assert.Equal(180, matrix.Elements[1]);
+ Assert.Equal(50, matrix.Elements[2]);
+ Assert.Equal(80, matrix.Elements[3]);
+ Assert.Equal(50, matrix.Elements[4]);
+ Assert.Equal(60, matrix.Elements[5]);
+
+ matrix = new Matrix(5, 3, 9, 2, 2, 1);
+ matrix.Shear(10, 20);
+
+ Assert.Equal(185, matrix.Elements[0]);
+ Assert.Equal(43, matrix.Elements[1]);
+ Assert.Equal(59, matrix.Elements[2]);
+ Assert.Equal(32, matrix.Elements[3]);
+ Assert.Equal(2, matrix.Elements[4]);
+ Assert.Equal(1, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Shear_InvalidOrder()
+ {
+ Assert.Throws(() => new Matrix().Shear(-1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformPoints()
+ {
+ Matrix matrix = new Matrix(2, 4, 6, 8, 10, 12);
+ PointF[] pointsF = new PointF[] { new PointF(2, 4), new PointF(4, 8) };
+ matrix.TransformPoints(pointsF);
+
+ Assert.Equal(38, pointsF[0].X);
+ Assert.Equal(52, pointsF[0].Y);
+ Assert.Equal(66, pointsF[1].X);
+ Assert.Equal(92, pointsF[1].Y);
+
+ Point[] points = new Point[] { new Point(2, 4), new Point(4, 8) };
+ matrix.TransformPoints(points);
+ Assert.Equal(38, pointsF[0].X);
+ Assert.Equal(52, pointsF[0].Y);
+ Assert.Equal(66, pointsF[1].X);
+ Assert.Equal(92, pointsF[1].Y);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformPoints_Point_Null()
+ {
+ Assert.Throws(() => new Matrix().TransformPoints((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformPoints_PointF_Null()
+ {
+ Assert.Throws(() => new Matrix().TransformPoints((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformPoints_Point_Empty()
+ {
+ Assert.Throws(() => new Matrix().TransformPoints(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformPoints_PointF_Empty()
+ {
+ Assert.Throws(() => new Matrix().TransformPoints(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformVectors()
+ {
+ Matrix matrix = new Matrix(2, 4, 6, 8, 10, 12);
+ PointF[] pointsF = new PointF[] { new PointF(2, 4), new PointF(4, 8) };
+ matrix.TransformVectors(pointsF);
+
+ Assert.Equal(28, pointsF[0].X);
+ Assert.Equal(40, pointsF[0].Y);
+ Assert.Equal(56, pointsF[1].X);
+ Assert.Equal(80, pointsF[1].Y);
+
+ Point[] points = new Point[] { new Point(2, 4), new Point(4, 8) };
+ matrix.TransformVectors(points);
+ Assert.Equal(28, pointsF[0].X);
+ Assert.Equal(40, pointsF[0].Y);
+ Assert.Equal(56, pointsF[1].X);
+ Assert.Equal(80, pointsF[1].Y);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformVectors_Point_Null()
+ {
+ Assert.Throws(() => new Matrix().TransformVectors((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformVectors_PointF_Null()
+ {
+ Assert.Throws(() => new Matrix().TransformVectors((PointF[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformVectors_Point_Empty()
+ {
+ Assert.Throws(() => new Matrix().TransformVectors(new Point[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TransformVectors_PointF_Empty()
+ {
+ Assert.Throws(() => new Matrix().TransformVectors(new PointF[0]));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Translate()
+ {
+ Matrix matrix = new Matrix(2, 4, 6, 8, 10, 12);
+ matrix.Translate(5, 10);
+
+ Assert.Equal(2, matrix.Elements[0]);
+ Assert.Equal(4, matrix.Elements[1]);
+ Assert.Equal(6, matrix.Elements[2]);
+ Assert.Equal(8, matrix.Elements[3]);
+ Assert.Equal(80, matrix.Elements[4]);
+ Assert.Equal(112, matrix.Elements[5]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Translate_InvalidOrder()
+ {
+ Assert.Throws(() => new Matrix().Translate(-1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void VectorTransformPoints_Null()
+ {
+ Assert.Throws(() => new Matrix().VectorTransformPoints((Point[])null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void VectorTransformPoints_Empty()
+ {
+ Assert.Throws(() => new Matrix().VectorTransformPoints(new Point[0]));
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/EmfPlusRecordTypeTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/EmfPlusRecordTypeTest.cs
new file mode 100644
index 000000000000..0f565f750aed
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/EmfPlusRecordTypeTest.cs
@@ -0,0 +1,311 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// EmfPlusRecordType class unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Imaging
+{
+
+ public class EmfPlusRecordTypeTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmfRecords()
+ {
+ Assert.Equal(1, (int)EmfPlusRecordType.EmfMin);
+ Assert.Equal(1, (int)EmfPlusRecordType.EmfHeader);
+ Assert.Equal(2, (int)EmfPlusRecordType.EmfPolyBezier);
+ Assert.Equal(3, (int)EmfPlusRecordType.EmfPolygon);
+ Assert.Equal(4, (int)EmfPlusRecordType.EmfPolyline);
+ Assert.Equal(5, (int)EmfPlusRecordType.EmfPolyBezierTo);
+ Assert.Equal(6, (int)EmfPlusRecordType.EmfPolyLineTo);
+ Assert.Equal(7, (int)EmfPlusRecordType.EmfPolyPolyline);
+ Assert.Equal(8, (int)EmfPlusRecordType.EmfPolyPolygon);
+ Assert.Equal(9, (int)EmfPlusRecordType.EmfSetWindowExtEx);
+ Assert.Equal(10, (int)EmfPlusRecordType.EmfSetWindowOrgEx);
+ Assert.Equal(11, (int)EmfPlusRecordType.EmfSetViewportExtEx);
+ Assert.Equal(12, (int)EmfPlusRecordType.EmfSetViewportOrgEx);
+ Assert.Equal(13, (int)EmfPlusRecordType.EmfSetBrushOrgEx);
+ Assert.Equal(14, (int)EmfPlusRecordType.EmfEof);
+ Assert.Equal(15, (int)EmfPlusRecordType.EmfSetPixelV);
+ Assert.Equal(16, (int)EmfPlusRecordType.EmfSetMapperFlags);
+ Assert.Equal(17, (int)EmfPlusRecordType.EmfSetMapMode);
+ Assert.Equal(18, (int)EmfPlusRecordType.EmfSetBkMode);
+ Assert.Equal(19, (int)EmfPlusRecordType.EmfSetPolyFillMode);
+ Assert.Equal(20, (int)EmfPlusRecordType.EmfSetROP2);
+ Assert.Equal(21, (int)EmfPlusRecordType.EmfSetStretchBltMode);
+ Assert.Equal(22, (int)EmfPlusRecordType.EmfSetTextAlign);
+ Assert.Equal(23, (int)EmfPlusRecordType.EmfSetColorAdjustment);
+ Assert.Equal(24, (int)EmfPlusRecordType.EmfSetTextColor);
+ Assert.Equal(25, (int)EmfPlusRecordType.EmfSetBkColor);
+ Assert.Equal(26, (int)EmfPlusRecordType.EmfOffsetClipRgn);
+ Assert.Equal(27, (int)EmfPlusRecordType.EmfMoveToEx);
+ Assert.Equal(28, (int)EmfPlusRecordType.EmfSetMetaRgn);
+ Assert.Equal(29, (int)EmfPlusRecordType.EmfExcludeClipRect);
+ Assert.Equal(30, (int)EmfPlusRecordType.EmfIntersectClipRect);
+ Assert.Equal(31, (int)EmfPlusRecordType.EmfScaleViewportExtEx);
+ Assert.Equal(32, (int)EmfPlusRecordType.EmfScaleWindowExtEx);
+ Assert.Equal(33, (int)EmfPlusRecordType.EmfSaveDC);
+ Assert.Equal(34, (int)EmfPlusRecordType.EmfRestoreDC);
+ Assert.Equal(35, (int)EmfPlusRecordType.EmfSetWorldTransform);
+ Assert.Equal(36, (int)EmfPlusRecordType.EmfModifyWorldTransform);
+ Assert.Equal(37, (int)EmfPlusRecordType.EmfSelectObject);
+ Assert.Equal(38, (int)EmfPlusRecordType.EmfCreatePen);
+ Assert.Equal(39, (int)EmfPlusRecordType.EmfCreateBrushIndirect);
+ Assert.Equal(40, (int)EmfPlusRecordType.EmfDeleteObject);
+ Assert.Equal(41, (int)EmfPlusRecordType.EmfAngleArc);
+ Assert.Equal(42, (int)EmfPlusRecordType.EmfEllipse);
+ Assert.Equal(43, (int)EmfPlusRecordType.EmfRectangle);
+ Assert.Equal(44, (int)EmfPlusRecordType.EmfRoundRect);
+ Assert.Equal(45, (int)EmfPlusRecordType.EmfRoundArc);
+ Assert.Equal(46, (int)EmfPlusRecordType.EmfChord);
+ Assert.Equal(47, (int)EmfPlusRecordType.EmfPie);
+ Assert.Equal(48, (int)EmfPlusRecordType.EmfSelectPalette);
+ Assert.Equal(49, (int)EmfPlusRecordType.EmfCreatePalette);
+ Assert.Equal(50, (int)EmfPlusRecordType.EmfSetPaletteEntries);
+ Assert.Equal(51, (int)EmfPlusRecordType.EmfResizePalette);
+ Assert.Equal(52, (int)EmfPlusRecordType.EmfRealizePalette);
+ Assert.Equal(53, (int)EmfPlusRecordType.EmfExtFloodFill);
+ Assert.Equal(54, (int)EmfPlusRecordType.EmfLineTo);
+ Assert.Equal(55, (int)EmfPlusRecordType.EmfArcTo);
+ Assert.Equal(56, (int)EmfPlusRecordType.EmfPolyDraw);
+ Assert.Equal(57, (int)EmfPlusRecordType.EmfSetArcDirection);
+ Assert.Equal(58, (int)EmfPlusRecordType.EmfSetMiterLimit);
+ Assert.Equal(59, (int)EmfPlusRecordType.EmfBeginPath);
+ Assert.Equal(60, (int)EmfPlusRecordType.EmfEndPath);
+ Assert.Equal(61, (int)EmfPlusRecordType.EmfCloseFigure);
+ Assert.Equal(62, (int)EmfPlusRecordType.EmfFillPath);
+ Assert.Equal(63, (int)EmfPlusRecordType.EmfStrokeAndFillPath);
+ Assert.Equal(64, (int)EmfPlusRecordType.EmfStrokePath);
+ Assert.Equal(65, (int)EmfPlusRecordType.EmfFlattenPath);
+ Assert.Equal(66, (int)EmfPlusRecordType.EmfWidenPath);
+ Assert.Equal(67, (int)EmfPlusRecordType.EmfSelectClipPath);
+ Assert.Equal(68, (int)EmfPlusRecordType.EmfAbortPath);
+ Assert.Equal(69, (int)EmfPlusRecordType.EmfReserved069);
+ Assert.Equal(70, (int)EmfPlusRecordType.EmfGdiComment);
+ Assert.Equal(71, (int)EmfPlusRecordType.EmfFillRgn);
+ Assert.Equal(72, (int)EmfPlusRecordType.EmfFrameRgn);
+ Assert.Equal(73, (int)EmfPlusRecordType.EmfInvertRgn);
+ Assert.Equal(74, (int)EmfPlusRecordType.EmfPaintRgn);
+ Assert.Equal(75, (int)EmfPlusRecordType.EmfExtSelectClipRgn);
+ Assert.Equal(76, (int)EmfPlusRecordType.EmfBitBlt);
+ Assert.Equal(77, (int)EmfPlusRecordType.EmfStretchBlt);
+ Assert.Equal(78, (int)EmfPlusRecordType.EmfMaskBlt);
+ Assert.Equal(79, (int)EmfPlusRecordType.EmfPlgBlt);
+ Assert.Equal(80, (int)EmfPlusRecordType.EmfSetDIBitsToDevice);
+ Assert.Equal(81, (int)EmfPlusRecordType.EmfStretchDIBits);
+ Assert.Equal(82, (int)EmfPlusRecordType.EmfExtCreateFontIndirect);
+ Assert.Equal(83, (int)EmfPlusRecordType.EmfExtTextOutA);
+ Assert.Equal(84, (int)EmfPlusRecordType.EmfExtTextOutW);
+ Assert.Equal(85, (int)EmfPlusRecordType.EmfPolyBezier16);
+ Assert.Equal(86, (int)EmfPlusRecordType.EmfPolygon16);
+ Assert.Equal(87, (int)EmfPlusRecordType.EmfPolyline16);
+ Assert.Equal(88, (int)EmfPlusRecordType.EmfPolyBezierTo16);
+ Assert.Equal(89, (int)EmfPlusRecordType.EmfPolylineTo16);
+ Assert.Equal(90, (int)EmfPlusRecordType.EmfPolyPolyline16);
+ Assert.Equal(91, (int)EmfPlusRecordType.EmfPolyPolygon16);
+ Assert.Equal(92, (int)EmfPlusRecordType.EmfPolyDraw16);
+ Assert.Equal(93, (int)EmfPlusRecordType.EmfCreateMonoBrush);
+ Assert.Equal(94, (int)EmfPlusRecordType.EmfCreateDibPatternBrushPt);
+ Assert.Equal(95, (int)EmfPlusRecordType.EmfExtCreatePen);
+ Assert.Equal(96, (int)EmfPlusRecordType.EmfPolyTextOutA);
+ Assert.Equal(97, (int)EmfPlusRecordType.EmfPolyTextOutW);
+ Assert.Equal(98, (int)EmfPlusRecordType.EmfSetIcmMode);
+ Assert.Equal(99, (int)EmfPlusRecordType.EmfCreateColorSpace);
+ Assert.Equal(100, (int)EmfPlusRecordType.EmfSetColorSpace);
+ Assert.Equal(101, (int)EmfPlusRecordType.EmfDeleteColorSpace);
+ Assert.Equal(102, (int)EmfPlusRecordType.EmfGlsRecord);
+ Assert.Equal(103, (int)EmfPlusRecordType.EmfGlsBoundedRecord);
+ Assert.Equal(104, (int)EmfPlusRecordType.EmfPixelFormat);
+ Assert.Equal(105, (int)EmfPlusRecordType.EmfDrawEscape);
+ Assert.Equal(106, (int)EmfPlusRecordType.EmfExtEscape);
+ Assert.Equal(107, (int)EmfPlusRecordType.EmfStartDoc);
+ Assert.Equal(108, (int)EmfPlusRecordType.EmfSmallTextOut);
+ Assert.Equal(109, (int)EmfPlusRecordType.EmfForceUfiMapping);
+ Assert.Equal(110, (int)EmfPlusRecordType.EmfNamedEscpae);
+ Assert.Equal(111, (int)EmfPlusRecordType.EmfColorCorrectPalette);
+ Assert.Equal(112, (int)EmfPlusRecordType.EmfSetIcmProfileA);
+ Assert.Equal(113, (int)EmfPlusRecordType.EmfSetIcmProfileW);
+ Assert.Equal(114, (int)EmfPlusRecordType.EmfAlphaBlend);
+ Assert.Equal(115, (int)EmfPlusRecordType.EmfSetLayout);
+ Assert.Equal(116, (int)EmfPlusRecordType.EmfTransparentBlt);
+ Assert.Equal(117, (int)EmfPlusRecordType.EmfReserved117);
+ Assert.Equal(118, (int)EmfPlusRecordType.EmfGradientFill);
+ Assert.Equal(119, (int)EmfPlusRecordType.EmfSetLinkedUfis);
+ Assert.Equal(120, (int)EmfPlusRecordType.EmfSetTextJustification);
+ Assert.Equal(121, (int)EmfPlusRecordType.EmfColorMatchToTargetW);
+ Assert.Equal(122, (int)EmfPlusRecordType.EmfCreateColorSpaceW);
+ Assert.Equal(122, (int)EmfPlusRecordType.EmfMax);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmfPlusRecords()
+ {
+ Assert.Equal(16384, (int)EmfPlusRecordType.EmfPlusRecordBase);
+ Assert.Equal(16384, (int)EmfPlusRecordType.Invalid);
+ Assert.Equal(16385, (int)EmfPlusRecordType.Min);
+ Assert.Equal(16385, (int)EmfPlusRecordType.Header);
+ Assert.Equal(16386, (int)EmfPlusRecordType.EndOfFile);
+ Assert.Equal(16387, (int)EmfPlusRecordType.Comment);
+ Assert.Equal(16388, (int)EmfPlusRecordType.GetDC);
+ Assert.Equal(16389, (int)EmfPlusRecordType.MultiFormatStart);
+ Assert.Equal(16390, (int)EmfPlusRecordType.MultiFormatSection);
+ Assert.Equal(16391, (int)EmfPlusRecordType.MultiFormatEnd);
+ Assert.Equal(16392, (int)EmfPlusRecordType.Object);
+ Assert.Equal(16393, (int)EmfPlusRecordType.Clear);
+ Assert.Equal(16394, (int)EmfPlusRecordType.FillRects);
+ Assert.Equal(16395, (int)EmfPlusRecordType.DrawRects);
+ Assert.Equal(16396, (int)EmfPlusRecordType.FillPolygon);
+ Assert.Equal(16397, (int)EmfPlusRecordType.DrawLines);
+ Assert.Equal(16398, (int)EmfPlusRecordType.FillEllipse);
+ Assert.Equal(16399, (int)EmfPlusRecordType.DrawEllipse);
+ Assert.Equal(16400, (int)EmfPlusRecordType.FillPie);
+ Assert.Equal(16401, (int)EmfPlusRecordType.DrawPie);
+ Assert.Equal(16402, (int)EmfPlusRecordType.DrawArc);
+ Assert.Equal(16403, (int)EmfPlusRecordType.FillRegion);
+ Assert.Equal(16404, (int)EmfPlusRecordType.FillPath);
+ Assert.Equal(16405, (int)EmfPlusRecordType.DrawPath);
+ Assert.Equal(16406, (int)EmfPlusRecordType.FillClosedCurve);
+ Assert.Equal(16407, (int)EmfPlusRecordType.DrawClosedCurve);
+ Assert.Equal(16408, (int)EmfPlusRecordType.DrawCurve);
+ Assert.Equal(16409, (int)EmfPlusRecordType.DrawBeziers);
+ Assert.Equal(16410, (int)EmfPlusRecordType.DrawImage);
+ Assert.Equal(16411, (int)EmfPlusRecordType.DrawImagePoints);
+ Assert.Equal(16412, (int)EmfPlusRecordType.DrawString);
+ Assert.Equal(16413, (int)EmfPlusRecordType.SetRenderingOrigin);
+ Assert.Equal(16414, (int)EmfPlusRecordType.SetAntiAliasMode);
+ Assert.Equal(16415, (int)EmfPlusRecordType.SetTextRenderingHint);
+ Assert.Equal(16416, (int)EmfPlusRecordType.SetTextContrast);
+ Assert.Equal(16417, (int)EmfPlusRecordType.SetInterpolationMode);
+ Assert.Equal(16418, (int)EmfPlusRecordType.SetPixelOffsetMode);
+ Assert.Equal(16419, (int)EmfPlusRecordType.SetCompositingMode);
+ Assert.Equal(16420, (int)EmfPlusRecordType.SetCompositingQuality);
+ Assert.Equal(16421, (int)EmfPlusRecordType.Save);
+ Assert.Equal(16422, (int)EmfPlusRecordType.Restore);
+ Assert.Equal(16423, (int)EmfPlusRecordType.BeginContainer);
+ Assert.Equal(16424, (int)EmfPlusRecordType.BeginContainerNoParams);
+ Assert.Equal(16425, (int)EmfPlusRecordType.EndContainer);
+ Assert.Equal(16426, (int)EmfPlusRecordType.SetWorldTransform);
+ Assert.Equal(16427, (int)EmfPlusRecordType.ResetWorldTransform);
+ Assert.Equal(16428, (int)EmfPlusRecordType.MultiplyWorldTransform);
+ Assert.Equal(16429, (int)EmfPlusRecordType.TranslateWorldTransform);
+ Assert.Equal(16430, (int)EmfPlusRecordType.ScaleWorldTransform);
+ Assert.Equal(16431, (int)EmfPlusRecordType.RotateWorldTransform);
+ Assert.Equal(16432, (int)EmfPlusRecordType.SetPageTransform);
+ Assert.Equal(16433, (int)EmfPlusRecordType.ResetClip);
+ Assert.Equal(16434, (int)EmfPlusRecordType.SetClipRect);
+ Assert.Equal(16435, (int)EmfPlusRecordType.SetClipPath);
+ Assert.Equal(16436, (int)EmfPlusRecordType.SetClipRegion);
+ Assert.Equal(16437, (int)EmfPlusRecordType.OffsetClip);
+ Assert.Equal(16438, (int)EmfPlusRecordType.DrawDriverString);
+ Assert.Equal(16438, (int)EmfPlusRecordType.Max);
+ Assert.Equal(16439, (int)EmfPlusRecordType.Total);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WmfRecords()
+ {
+ Assert.Equal(65536, (int)EmfPlusRecordType.WmfRecordBase);
+ Assert.Equal(65566, (int)EmfPlusRecordType.WmfSaveDC);
+ Assert.Equal(65589, (int)EmfPlusRecordType.WmfRealizePalette);
+ Assert.Equal(65591, (int)EmfPlusRecordType.WmfSetPalEntries);
+ Assert.Equal(65783, (int)EmfPlusRecordType.WmfCreatePalette);
+ Assert.Equal(65794, (int)EmfPlusRecordType.WmfSetBkMode);
+ Assert.Equal(65795, (int)EmfPlusRecordType.WmfSetMapMode);
+ Assert.Equal(65796, (int)EmfPlusRecordType.WmfSetROP2);
+ Assert.Equal(65797, (int)EmfPlusRecordType.WmfSetRelAbs);
+ Assert.Equal(65798, (int)EmfPlusRecordType.WmfSetPolyFillMode);
+ Assert.Equal(65799, (int)EmfPlusRecordType.WmfSetStretchBltMode);
+ Assert.Equal(65800, (int)EmfPlusRecordType.WmfSetTextCharExtra);
+ Assert.Equal(65831, (int)EmfPlusRecordType.WmfRestoreDC);
+ Assert.Equal(65834, (int)EmfPlusRecordType.WmfInvertRegion);
+ Assert.Equal(65835, (int)EmfPlusRecordType.WmfPaintRegion);
+ Assert.Equal(65836, (int)EmfPlusRecordType.WmfSelectClipRegion);
+ Assert.Equal(65837, (int)EmfPlusRecordType.WmfSelectObject);
+ Assert.Equal(65838, (int)EmfPlusRecordType.WmfSetTextAlign);
+ Assert.Equal(65849, (int)EmfPlusRecordType.WmfResizePalette);
+ Assert.Equal(65858, (int)EmfPlusRecordType.WmfDibCreatePatternBrush);
+ Assert.Equal(65865, (int)EmfPlusRecordType.WmfSetLayout);
+ Assert.Equal(66032, (int)EmfPlusRecordType.WmfDeleteObject);
+ Assert.Equal(66041, (int)EmfPlusRecordType.WmfCreatePatternBrush);
+ Assert.Equal(66049, (int)EmfPlusRecordType.WmfSetBkColor);
+ Assert.Equal(66057, (int)EmfPlusRecordType.WmfSetTextColor);
+ Assert.Equal(66058, (int)EmfPlusRecordType.WmfSetTextJustification);
+ Assert.Equal(66059, (int)EmfPlusRecordType.WmfSetWindowOrg);
+ Assert.Equal(66060, (int)EmfPlusRecordType.WmfSetWindowExt);
+ Assert.Equal(66061, (int)EmfPlusRecordType.WmfSetViewportOrg);
+ Assert.Equal(66062, (int)EmfPlusRecordType.WmfSetViewportExt);
+ Assert.Equal(66063, (int)EmfPlusRecordType.WmfOffsetWindowOrg);
+ Assert.Equal(66065, (int)EmfPlusRecordType.WmfOffsetViewportOrg);
+ Assert.Equal(66067, (int)EmfPlusRecordType.WmfLineTo);
+ Assert.Equal(66068, (int)EmfPlusRecordType.WmfMoveTo);
+ Assert.Equal(66080, (int)EmfPlusRecordType.WmfOffsetCilpRgn);
+ Assert.Equal(66088, (int)EmfPlusRecordType.WmfFillRegion);
+ Assert.Equal(66097, (int)EmfPlusRecordType.WmfSetMapperFlags);
+ Assert.Equal(66100, (int)EmfPlusRecordType.WmfSelectPalette);
+ Assert.Equal(66298, (int)EmfPlusRecordType.WmfCreatePenIndirect);
+ Assert.Equal(66299, (int)EmfPlusRecordType.WmfCreateFontIndirect);
+ Assert.Equal(66300, (int)EmfPlusRecordType.WmfCreateBrushIndirect);
+ Assert.Equal(66340, (int)EmfPlusRecordType.WmfPolygon);
+ Assert.Equal(66341, (int)EmfPlusRecordType.WmfPolyline);
+ Assert.Equal(66576, (int)EmfPlusRecordType.WmfScaleWindowExt);
+ Assert.Equal(66578, (int)EmfPlusRecordType.WmfScaleViewportExt);
+ Assert.Equal(66581, (int)EmfPlusRecordType.WmfExcludeClipRect);
+ Assert.Equal(66582, (int)EmfPlusRecordType.WmfIntersectClipRect);
+ Assert.Equal(66584, (int)EmfPlusRecordType.WmfEllipse);
+ Assert.Equal(66585, (int)EmfPlusRecordType.WmfFloodFill);
+ Assert.Equal(66587, (int)EmfPlusRecordType.WmfRectangle);
+ Assert.Equal(66591, (int)EmfPlusRecordType.WmfSetPixel);
+ Assert.Equal(66601, (int)EmfPlusRecordType.WmfFrameRegion);
+ Assert.Equal(66614, (int)EmfPlusRecordType.WmfAnimatePalette);
+ Assert.Equal(66849, (int)EmfPlusRecordType.WmfTextOut);
+ Assert.Equal(66872, (int)EmfPlusRecordType.WmfPolyPolygon);
+ Assert.Equal(66888, (int)EmfPlusRecordType.WmfExtFloodFill);
+ Assert.Equal(67100, (int)EmfPlusRecordType.WmfRoundRect);
+ Assert.Equal(67101, (int)EmfPlusRecordType.WmfPatBlt);
+ Assert.Equal(67110, (int)EmfPlusRecordType.WmfEscape);
+ Assert.Equal(67327, (int)EmfPlusRecordType.WmfCreateRegion);
+ Assert.Equal(67607, (int)EmfPlusRecordType.WmfArc);
+ Assert.Equal(67610, (int)EmfPlusRecordType.WmfPie);
+ Assert.Equal(67632, (int)EmfPlusRecordType.WmfChord);
+ Assert.Equal(67874, (int)EmfPlusRecordType.WmfBitBlt);
+ Assert.Equal(67904, (int)EmfPlusRecordType.WmfDibBitBlt);
+ Assert.Equal(68146, (int)EmfPlusRecordType.WmfExtTextOut);
+ Assert.Equal(68387, (int)EmfPlusRecordType.WmfStretchBlt);
+ Assert.Equal(68417, (int)EmfPlusRecordType.WmfDibStretchBlt);
+ Assert.Equal(68915, (int)EmfPlusRecordType.WmfSetDibToDev);
+ Assert.Equal(69443, (int)EmfPlusRecordType.WmfStretchDib);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/FrameDimensionTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/FrameDimensionTest.cs
new file mode 100644
index 000000000000..dbd396e2537d
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/FrameDimensionTest.cs
@@ -0,0 +1,79 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Imaging
+{
+
+ public class FrameDimensionTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Empty()
+ {
+ FrameDimension fd = new FrameDimension(Guid.Empty);
+ Assert.Equal("00000000-0000-0000-0000-000000000000", fd.Guid.ToString());
+ Assert.Equal(Guid.Empty.GetHashCode(), fd.GetHashCode());
+ Assert.Equal("[FrameDimension: 00000000-0000-0000-0000-000000000000]", fd.ToString());
+
+ Assert.True(fd.Equals(new FrameDimension(Guid.Empty)));
+ Assert.False(fd.Equals(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WellKnownValues()
+ {
+ Assert.Equal("7462dc86-6180-4c7e-8e3f-ee7333a7a483", FrameDimension.Page.Guid.ToString());
+ Assert.Equal("Page", FrameDimension.Page.ToString());
+ Assert.True(Object.ReferenceEquals(FrameDimension.Page, FrameDimension.Page));
+
+ Assert.Equal("84236f7b-3bd3-428f-8dab-4ea1439ca315", FrameDimension.Resolution.Guid.ToString());
+ Assert.Equal("Resolution", FrameDimension.Resolution.ToString());
+ Assert.True(Object.ReferenceEquals(FrameDimension.Resolution, FrameDimension.Resolution));
+
+ Assert.Equal("6aedbd6d-3fb5-418a-83a6-7f45229dc872", FrameDimension.Time.Guid.ToString());
+ Assert.Equal("Time", FrameDimension.Time.ToString());
+ Assert.True(Object.ReferenceEquals(FrameDimension.Time, FrameDimension.Time));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Equals()
+ {
+ FrameDimension fd = new FrameDimension(new Guid("7462dc86-6180-4c7e-8e3f-ee7333a7a483"));
+ // equals
+ Assert.True(fd.Equals(FrameDimension.Page));
+ // but ToString differs!
+ Assert.Equal("[FrameDimension: 7462dc86-6180-4c7e-8e3f-ee7333a7a483]", fd.ToString());
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestColorMatrix.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestColorMatrix.cs
new file mode 100644
index 000000000000..b97682cbf8c9
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestColorMatrix.cs
@@ -0,0 +1,290 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Authors:
+// Jordi Mas i Hernandez (jordi@ximian.com)
+// Sebastien Pouliot
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Imaging
+{
+
+ public class ColorMatrixTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Null()
+ {
+ Assert.Throws(() => new ColorMatrix(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_TooSmallArraySize()
+ {
+ Assert.Throws(() => new ColorMatrix(new float[][] { }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_TooWideArraySize()
+ {
+ Assert.Throws(() => new ColorMatrix(new float[][] {
+ new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f }
+ }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_TooTallArraySize()
+ {
+ Assert.Throws(() => new ColorMatrix(new float[][] {
+ new float[] { 0.0f },
+ new float[] { 1.0f },
+ new float[] { 2.0f },
+ new float[] { 3.0f },
+ new float[] { 4.0f },
+ new float[] { 5.0f }
+ }));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_TooBigArraySize()
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f },
+ new float[] { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f },
+ new float[] { 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f },
+ new float[] { 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f },
+ new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f },
+ new float[] { 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f }
+ });
+
+ Assert.Equal(0.0f, cm.Matrix00);
+ Assert.Equal(0.1f, cm.Matrix01);
+ Assert.Equal(0.2f, cm.Matrix02);
+ Assert.Equal(0.3f, cm.Matrix03);
+ Assert.Equal(0.4f, cm.Matrix04);
+ Assert.Equal(1.0f, cm.Matrix10);
+ Assert.Equal(1.1f, cm.Matrix11);
+ Assert.Equal(1.2f, cm.Matrix12);
+ Assert.Equal(1.3f, cm.Matrix13);
+ Assert.Equal(1.4f, cm.Matrix14);
+ Assert.Equal(2.0f, cm.Matrix20);
+ Assert.Equal(2.1f, cm.Matrix21);
+ Assert.Equal(2.2f, cm.Matrix22);
+ Assert.Equal(2.3f, cm.Matrix23);
+ Assert.Equal(2.4f, cm.Matrix24);
+ Assert.Equal(3.0f, cm.Matrix30);
+ Assert.Equal(3.1f, cm.Matrix31);
+ Assert.Equal(3.2f, cm.Matrix32);
+ Assert.Equal(3.3f, cm.Matrix33);
+ Assert.Equal(3.4f, cm.Matrix34);
+ Assert.Equal(4.0f, cm.Matrix40);
+ Assert.Equal(4.1f, cm.Matrix41);
+ Assert.Equal(4.2f, cm.Matrix42);
+ Assert.Equal(4.3f, cm.Matrix43);
+ Assert.Equal(4.4f, cm.Matrix44);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TooBigItems()
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] { 0.0f, 0.1f, 0.2f, 0.3f, 0.4f, 0.5f },
+ new float[] { 1.0f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f },
+ new float[] { 2.0f, 2.1f, 2.2f, 2.3f, 2.4f, 2.5f },
+ new float[] { 3.0f, 3.1f, 3.2f, 3.3f, 3.4f, 3.5f },
+ new float[] { 4.0f, 4.1f, 4.2f, 4.3f, 4.4f, 4.5f },
+ new float[] { 5.0f, 5.1f, 5.2f, 5.3f, 5.4f, 5.5f }
+ });
+ Assert.Throws(() => { var x = cm[5, 5]; });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DefaultConstructor()
+ {
+ ColorMatrix cm = new ColorMatrix();
+
+ Assert.Equal(1, cm.Matrix00);
+ Assert.Equal(1, cm.Matrix11);
+ Assert.Equal(1, cm.Matrix22);
+ Assert.Equal(1, cm.Matrix33);
+ Assert.Equal(1, cm.Matrix44);
+ Assert.Equal(0, cm.Matrix01);
+ Assert.Equal(0, cm.Matrix02);
+ Assert.Equal(0, cm.Matrix03);
+ Assert.Equal(0, cm.Matrix04);
+ Assert.Equal(0, cm.Matrix10);
+ Assert.Equal(0, cm.Matrix12);
+ Assert.Equal(0, cm.Matrix13);
+ Assert.Equal(0, cm.Matrix14);
+ Assert.Equal(0, cm.Matrix20);
+ Assert.Equal(0, cm.Matrix21);
+ Assert.Equal(0, cm.Matrix23);
+ Assert.Equal(0, cm.Matrix24);
+ Assert.Equal(0, cm.Matrix30);
+ Assert.Equal(0, cm.Matrix31);
+ Assert.Equal(0, cm.Matrix32);
+ Assert.Equal(0, cm.Matrix34);
+ Assert.Equal(0, cm.Matrix40);
+ Assert.Equal(0, cm.Matrix41);
+ Assert.Equal(0, cm.Matrix42);
+ Assert.Equal(0, cm.Matrix43);
+ Assert.Equal(100, Marshal.SizeOf(cm));
+ Assert.Equal(100, Marshal.SizeOf(typeof(ColorMatrix)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ConstructorArrayAndMethods()
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {0.393f, 0.349f, 0.272f, 0, 0},
+ new float[] {0.769f, 0.686f, 0.534f, 0, 0},
+ new float[] {0.189f, 0.168f, 0.131f, 0, 0},
+ new float[] { 0, 0, 0, 1, 0},
+ new float[] { 0, 0, 0, 0, 1}
+ });
+
+ Assert.Equal(0.393f, cm.Matrix00);
+ Assert.Equal(0.349f, cm.Matrix01);
+ Assert.Equal(0.272f, cm.Matrix02);
+ Assert.Equal(0, cm.Matrix03);
+ Assert.Equal(0, cm.Matrix04);
+
+ Assert.Equal(0.769f, cm.Matrix10);
+ Assert.Equal(0.686f, cm.Matrix11);
+ Assert.Equal(0.534f, cm.Matrix12);
+ Assert.Equal(0, cm.Matrix13);
+ Assert.Equal(0, cm.Matrix14);
+
+ Assert.Equal(0.189f, cm.Matrix20);
+ Assert.Equal(0.168f, cm.Matrix21);
+ Assert.Equal(0.131f, cm.Matrix22);
+ Assert.Equal(0, cm.Matrix23);
+ Assert.Equal(0, cm.Matrix24);
+
+ Assert.Equal(0, cm.Matrix30);
+ Assert.Equal(0, cm.Matrix31);
+ Assert.Equal(0, cm.Matrix32);
+ Assert.Equal(1, cm.Matrix33);
+ Assert.Equal(0, cm.Matrix34);
+
+ Assert.Equal(0, cm.Matrix40);
+ Assert.Equal(0, cm.Matrix41);
+ Assert.Equal(0, cm.Matrix42);
+ Assert.Equal(0, cm.Matrix43);
+ Assert.Equal(1, cm.Matrix44);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IndexerProperty()
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0},
+ new float[] {0.5f, 1, 0, 0, 0},
+ new float[] {0, 0.1f, 1.5f, 0, 0},
+ new float[] {0.5f, 3, 0.5f, 1, 0},
+ new float[] {0, 0, 0, 0, 0}
+ });
+
+ Assert.Equal(1, cm[0, 0]);
+ Assert.Equal(0, cm[0, 1]);
+ Assert.Equal(0, cm[0, 2]);
+ Assert.Equal(0, cm[0, 3]);
+ Assert.Equal(0, cm[0, 4]);
+
+ Assert.Equal(0.5f, cm[1, 0]);
+ Assert.Equal(1, cm[1, 1]);
+ Assert.Equal(0, cm[1, 2]);
+ Assert.Equal(0, cm[1, 3]);
+ Assert.Equal(0, cm[1, 4]);
+
+ Assert.Equal(0, cm[2, 0]);
+ Assert.Equal(0.1f, cm[2, 1]);
+ Assert.Equal(1.5f, cm[2, 2]);
+ Assert.Equal(0, cm[2, 3]);
+ Assert.Equal(0, cm[2, 4]);
+
+ Assert.Equal(0.5f, cm[3, 0]);
+ Assert.Equal(3, cm[3, 1]);
+ Assert.Equal(0.5f, cm[3, 2]);
+ Assert.Equal(1, cm[3, 3]);
+ Assert.Equal(0, cm[3, 4]);
+
+ Assert.Equal(0, cm[4, 0]);
+ Assert.Equal(0, cm[4, 1]);
+ Assert.Equal(0, cm[4, 2]);
+ Assert.Equal(0, cm[4, 3]);
+ Assert.Equal(0, cm[4, 4]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IndividualProperties()
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0},
+ new float[] {0.5f, 1, 0, 0, 0},
+ new float[] {0, 0.1f, 1.5f, 0, 0},
+ new float[] {0.5f, 3, 0.5f, 1, 0},
+ new float[] {0, 0, 0, 0, 0}
+ });
+
+ Assert.Equal(1, cm.Matrix00);
+ Assert.Equal(0, cm.Matrix01);
+ Assert.Equal(0, cm.Matrix02);
+ Assert.Equal(0, cm.Matrix03);
+ Assert.Equal(0, cm.Matrix04);
+
+ Assert.Equal(0.5f, cm.Matrix10);
+ Assert.Equal(1, cm.Matrix11);
+ Assert.Equal(0, cm.Matrix12);
+ Assert.Equal(0, cm.Matrix13);
+ Assert.Equal(0, cm.Matrix14);
+
+ Assert.Equal(0, cm.Matrix20);
+ Assert.Equal(0.1f, cm.Matrix21);
+ Assert.Equal(1.5f, cm.Matrix22);
+ Assert.Equal(0, cm.Matrix23);
+ Assert.Equal(0, cm.Matrix24);
+
+ Assert.Equal(0.5f, cm.Matrix30);
+ Assert.Equal(3, cm.Matrix31);
+ Assert.Equal(0.5f, cm.Matrix32);
+ Assert.Equal(1, cm.Matrix33);
+ Assert.Equal(0, cm.Matrix34);
+
+ Assert.Equal(0, cm.Matrix40);
+ Assert.Equal(0, cm.Matrix41);
+ Assert.Equal(0, cm.Matrix42);
+ Assert.Equal(0, cm.Matrix43);
+ Assert.Equal(0, cm.Matrix44);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageAttributes.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageAttributes.cs
new file mode 100644
index 000000000000..42d17c62c811
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageAttributes.cs
@@ -0,0 +1,482 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Copyright (C) 2005-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+// Authors:
+// Jordi Mas i Hernandez (jordi@ximian.com)
+// Sebastien Pouliot
+//
+
+using System;
+using System.IO;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Imaging
+{
+
+ public class ImageAttributesTest
+ {
+
+ static ColorMatrix global_color_matrix = new ColorMatrix(new float[][] {
+ new float[] {2, 0, 0, 0, 0}, //R
+ new float[] {0, 1, 0, 0, 0}, //G
+ new float[] {0, 0, 1, 0, 0}, //B
+ new float[] {0, 0, 0, 1, 0}, //A
+ new float[] {0.2f, 0, 0, 0, 0}, //Translation
+ });
+
+ static ColorMatrix global_gray_matrix = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0}, //R
+ new float[] {0, 2, 0, 0, 0}, //G
+ new float[] {0, 0, 3, 0, 0}, //B
+ new float[] {0, 0, 0, 1, 0}, //A
+ new float[] {0.5f, 0, 0, 0, 0}, //Translation
+ });
+
+ private static Color ProcessColorMatrix(Color color, ColorMatrix colorMatrix)
+ {
+ using (Bitmap bmp = new Bitmap(64, 64))
+ {
+ using (Graphics gr = Graphics.FromImage(bmp))
+ {
+ ImageAttributes imageAttr = new ImageAttributes();
+ bmp.SetPixel(0, 0, color);
+ imageAttr.SetColorMatrix(colorMatrix);
+ gr.DrawImage(bmp, new Rectangle(0, 0, 64, 64), 0, 0, 64, 64, GraphicsUnit.Pixel, imageAttr);
+ return bmp.GetPixel(0, 0);
+ }
+ }
+ }
+
+
+ // Text Color Matrix processing
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorMatrix1()
+ {
+ Color clr_src, clr_rslt;
+
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {2, 0, 0, 0, 0}, //R
+ new float[] {0, 1, 0, 0, 0}, //G
+ new float[] {0, 0, 1, 0, 0}, //B
+ new float[] {0, 0, 0, 1, 0}, //A
+ new float[] {0.2f, 0, 0, 0, 0}, //Translation
+ });
+
+ clr_src = Color.FromArgb(255, 100, 20, 50);
+ clr_rslt = ProcessColorMatrix(clr_src, cm);
+
+ Assert.Equal(Color.FromArgb(255, 251, 20, 50), clr_rslt);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorMatrix2()
+ {
+ Color clr_src, clr_rslt;
+
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0}, //R
+ new float[] {0, 1, 0, 0, 0}, //G
+ new float[] {0, 0, 1.5f, 0, 0}, //B
+ new float[] {0, 0, 0.5f, 1, 0}, //A
+ new float[] {0, 0, 0, 0, 0}, //Translation
+ });
+
+ clr_src = Color.FromArgb(255, 100, 40, 25);
+ clr_rslt = ProcessColorMatrix(clr_src, cm);
+ Assert.Equal(Color.FromArgb(255, 100, 40, 165), clr_rslt);
+ }
+
+ private void Bug80323(Color c)
+ {
+ string fileName = String.Format("80323-{0}.png", c.ToArgb().ToString("X"));
+
+ // test case from bug #80323
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0}, //R
+ new float[] {0, 1, 0, 0, 0}, //G
+ new float[] {0, 0, 1, 0, 0}, //B
+ new float[] {0, 0, 0, 0.5f, 0}, //A
+ new float[] {0, 0, 0, 0, 1}, //Translation
+ });
+
+ using (SolidBrush sb = new SolidBrush(c))
+ {
+ using (Bitmap bmp = new Bitmap(100, 100))
+ {
+ using (Graphics gr = Graphics.FromImage(bmp))
+ {
+ gr.FillRectangle(Brushes.White, 0, 0, 100, 100);
+ gr.FillEllipse(sb, 0, 0, 100, 100);
+ }
+ using (Bitmap b = new Bitmap(200, 100))
+ {
+ using (Graphics g = Graphics.FromImage(b))
+ {
+ g.FillRectangle(Brushes.White, 0, 0, 200, 100);
+
+ ImageAttributes ia = new ImageAttributes();
+ ia.SetColorMatrix(cm);
+ g.DrawImage(bmp, new Rectangle(0, 0, 100, 100), 0, 0, 100, 100, GraphicsUnit.Pixel, null);
+ g.DrawImage(bmp, new Rectangle(100, 0, 100, 100), 0, 0, 100, 100, GraphicsUnit.Pixel, ia);
+ }
+ b.Save(fileName);
+ Assert.Equal(Color.FromArgb(255, 255, 155, 155), b.GetPixel(50, 50));
+ Assert.Equal(Color.FromArgb(255, 255, 205, 205), b.GetPixel(150, 50));
+ }
+ }
+ }
+
+ File.Delete(fileName);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorMatrix_80323_UsingAlpha()
+ {
+ Bug80323(Color.FromArgb(100, 255, 0, 0));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ColorMatrix_80323_WithoutAlpha()
+ {
+ // this color is identical, once drawn over the bitmap, to Color.FromArgb (100, 255, 0, 0)
+ Bug80323(Color.FromArgb(255, 255, 155, 155));
+ }
+
+
+
+ private static Color ProcessColorMatrices(Color color, ColorMatrix colorMatrix, ColorMatrix grayMatrix, ColorMatrixFlag flags, ColorAdjustType type)
+ {
+ using (Bitmap bmp = new Bitmap(64, 64))
+ {
+ using (Graphics gr = Graphics.FromImage(bmp))
+ {
+ ImageAttributes imageAttr = new ImageAttributes();
+ bmp.SetPixel(0, 0, color);
+ imageAttr.SetColorMatrices(colorMatrix, grayMatrix, flags, type);
+ gr.DrawImage(bmp, new Rectangle(0, 0, 64, 64), 0, 0, 64, 64, GraphicsUnit.Pixel, imageAttr);
+ return bmp.GetPixel(0, 0);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_Null()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(null));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_Default()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Brush);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Pen);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Text);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_Default_Any()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Any));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_Default_Count()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, ColorAdjustType.Count));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Any()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Any));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Bitmap()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Bitmap));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Brush()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Brush));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Count()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Count));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Default()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Default));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Pen()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Pen));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_AltGrays_Text()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Text));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_SkipGrays()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Bitmap);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Brush);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Default);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Pen);
+ ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Text);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_SkipGrays_Any()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Any));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_SkipGrays_Count()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Count));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_InvalidFlag()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, (ColorMatrixFlag)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrix_InvalidType()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrix(global_color_matrix, ColorMatrixFlag.Default, (ColorAdjustType)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_Null_ColorMatrix()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrices(null, global_color_matrix));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_ColorMatrix_Null()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ ia.SetColorMatrices(global_color_matrix, null);
+ ia.SetColorMatrices(global_color_matrix, null, ColorMatrixFlag.Default);
+ ia.SetColorMatrices(global_color_matrix, null, ColorMatrixFlag.SkipGrays);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_ColorMatrix_Null_AltGrays()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrices(global_color_matrix, null, ColorMatrixFlag.AltGrays));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_ColorMatrix_ColorMatrix()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ ia.SetColorMatrices(global_color_matrix, global_color_matrix);
+ ia.SetColorMatrices(global_color_matrix, global_color_matrix, ColorMatrixFlag.Default);
+ ia.SetColorMatrices(global_color_matrix, global_color_matrix, ColorMatrixFlag.SkipGrays);
+ ia.SetColorMatrices(global_color_matrix, global_color_matrix, ColorMatrixFlag.AltGrays);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_Gray()
+ {
+ Color c = ProcessColorMatrices(Color.Gray, global_color_matrix, global_gray_matrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
+ Assert.Equal(0xFFFF8080, (uint)c.ToArgb());
+
+ c = ProcessColorMatrices(Color.Gray, global_color_matrix, global_gray_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Default);
+ Assert.Equal(0xFF808080, (uint)c.ToArgb());
+
+ c = ProcessColorMatrices(Color.Gray, global_color_matrix, global_gray_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Default);
+ Assert.Equal(0xFFFFFFFF, (uint)c.ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_Color()
+ {
+ Color c = ProcessColorMatrices(Color.MidnightBlue, global_color_matrix, global_gray_matrix, ColorMatrixFlag.Default, ColorAdjustType.Default);
+ Assert.Equal(0xFF651970, (uint)c.ToArgb());
+
+ c = ProcessColorMatrices(Color.MidnightBlue, global_color_matrix, global_gray_matrix, ColorMatrixFlag.SkipGrays, ColorAdjustType.Default);
+ Assert.Equal(0xFF651970, (uint)c.ToArgb());
+
+ c = ProcessColorMatrices(Color.MidnightBlue, global_color_matrix, global_gray_matrix, ColorMatrixFlag.AltGrays, ColorAdjustType.Default);
+ Assert.Equal(0xFF651970, (uint)c.ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_InvalidFlags()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrices(global_color_matrix, global_color_matrix, (ColorMatrixFlag)Int32.MinValue));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetColorMatrices_InvalidType()
+ {
+ using (ImageAttributes ia = new ImageAttributes())
+ {
+ Assert.Throws(() => ia.SetColorMatrices(global_color_matrix, global_color_matrix, ColorMatrixFlag.Default, (ColorAdjustType)Int32.MinValue));
+ }
+ }
+
+ private void Alpha(string prefix, int n, float a)
+ {
+ ColorMatrix cm = new ColorMatrix(new float[][] {
+ new float[] {1, 0, 0, 0, 0}, //R
+ new float[] {0, 1, 0, 0, 0}, //G
+ new float[] {0, 0, 1, 0, 0}, //B
+ new float[] {0, 0, 0, a, 0}, //A
+ new float[] {0, 0, 0, 0, 1}, //Translation
+ });
+
+ using (Bitmap bmp = new Bitmap(1, 4))
+ {
+ bmp.SetPixel(0, 0, Color.White);
+ bmp.SetPixel(0, 1, Color.Red);
+ bmp.SetPixel(0, 2, Color.Lime);
+ bmp.SetPixel(0, 3, Color.Blue);
+ using (Bitmap b = new Bitmap(1, 4))
+ {
+ using (Graphics g = Graphics.FromImage(b))
+ {
+ ImageAttributes ia = new ImageAttributes();
+ ia.SetColorMatrix(cm);
+ g.FillRectangle(Brushes.White, new Rectangle(0, 0, 1, 4));
+ g.DrawImage(bmp, new Rectangle(0, 0, 1, 4), 0, 0, 1, 4, GraphicsUnit.Pixel, ia);
+ Assert.Equal(Color.FromArgb(255, 255, 255, 255), b.GetPixel(0, 0));
+ int val = 255 - n;
+ Assert.Equal(Color.FromArgb(255, 255, val, val), b.GetPixel(0, 1));
+ Assert.Equal(Color.FromArgb(255, val, 255, val), b.GetPixel(0, 2));
+ Assert.Equal(Color.FromArgb(255, val, val, 255), b.GetPixel(0, 3));
+ }
+ }
+ }
+ }
+
+ [ActiveIssue(20844)]
+ public void ColorMatrixAlpha()
+ {
+ for (int i = 0; i < 256; i++)
+ {
+ Alpha(i.ToString(), i, (float)i / 255);
+ // generally color matrix are specified with values between [0..1]
+ Alpha("small-" + i.ToString(), i, (float)i / 255);
+ // but GDI+ also accept value > 1
+ Alpha("big-" + i.ToString(), i, 256 - i);
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageCodecInfo.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageCodecInfo.cs
new file mode 100644
index 000000000000..d6b9cee44a53
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Imaging/TestImageCodecInfo.cs
@@ -0,0 +1,279 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// ImageCodecInfo class testing unit
+//
+// Authors:
+// Jordi Mas i Hernà ndez (jordi@ximian.com)
+// Sebastien Pouliot
+//
+// (C) 2004 Ximian, Inc. http://www.ximian.com
+// Copyright (C) 2004-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using Xunit;
+using System.Collections;
+using System.Security.Permissions;
+using System.Text.RegularExpressions;
+
+namespace MonoTests.System.Drawing.Imaging
+{
+
+ public class ImageCodecInfoTest
+ {
+
+ Hashtable decoders;
+ Hashtable encoders;
+
+ ImageCodecInfo GetEncoder(Guid clsid)
+ {
+ return (ImageCodecInfo)encoders[clsid];
+ }
+
+ ImageCodecInfo GetDecoder(Guid clsid)
+ {
+ return (ImageCodecInfo)decoders[clsid];
+ }
+
+ public ImageCodecInfoTest()
+ {
+ decoders = new Hashtable();
+ encoders = new Hashtable();
+
+ foreach (ImageCodecInfo decoder in ImageCodecInfo.GetImageDecoders())
+ decoders[decoder.Clsid] = decoder;
+
+ foreach (ImageCodecInfo encoder in ImageCodecInfo.GetImageEncoders())
+ encoders[encoder.Clsid] = encoder;
+ }
+
+ static void Check(ImageCodecInfo e, ImageCodecInfo d, Guid FormatID, string CodecName, string DllName,
+ string FilenameExtension, ImageCodecFlags Flags, string FormatDescription,
+ string MimeType, int Version, int signatureLength, string mask, string pattern, string pattern2)
+ {
+ Regex extRegex = new Regex(@"^(\*\.\w+(;(\*\.\w+))*;)?" +
+ Regex.Escape(FilenameExtension) + @"(;\*\.\w+(;(\*\.\w+))*)?$",
+ RegexOptions.IgnoreCase | RegexOptions.Singleline);
+
+ if (e != null)
+ {
+ Assert.Equal(FormatID, e.FormatID);
+ Assert.True(e.CodecName.IndexOf(CodecName) >= 0,
+ "Encoder.CodecName contains " + CodecName);
+ Assert.Equal(DllName, e.DllName);
+ Assert.True(extRegex.IsMatch(e.FilenameExtension),
+ "Encoder.FilenameExtension is a right list with " + FilenameExtension);
+ Assert.Equal(Flags, e.Flags);
+ Assert.True(e.FormatDescription.IndexOf(FormatDescription) >= 0,
+ "Encoder.FormatDescription contains " + FormatDescription);
+ Assert.True(e.MimeType.IndexOf(MimeType) >= 0,
+ "Encoder.MimeType contains " + MimeType);
+
+ Assert.Equal(signatureLength, e.SignatureMasks.Length);
+ for (int i = 0; i < signatureLength; i++)
+ {
+ Assert.Equal(mask, BitConverter.ToString(e.SignatureMasks[i]));
+ }
+ Assert.Equal(signatureLength, e.SignaturePatterns.Length);
+ Assert.Equal(pattern, BitConverter.ToString(e.SignaturePatterns[0]));
+ if (pattern2 != null)
+ Assert.Equal(pattern2, BitConverter.ToString(e.SignaturePatterns[1]));
+ }
+ if (d != null)
+ {
+ Assert.Equal(FormatID, d.FormatID);
+ Assert.True(d.CodecName.IndexOf(CodecName) >= 0,
+ "Decoder.CodecName contains " + CodecName);
+ Assert.Equal(DllName, d.DllName);
+ Assert.True(extRegex.IsMatch(d.FilenameExtension),
+ "Decoder.FilenameExtension is a right list with " + FilenameExtension);
+ Assert.Equal(Flags, d.Flags);
+ Assert.True(d.FormatDescription.IndexOf(FormatDescription) >= 0,
+ "Decoder.FormatDescription contains " + FormatDescription);
+ Assert.True(d.MimeType.IndexOf(MimeType) >= 0,
+ "Decoder.MimeType contains " + MimeType);
+
+ Assert.Equal(signatureLength, d.SignatureMasks.Length);
+ for (int i = 0; i < signatureLength; i++)
+ {
+ Assert.Equal(mask, BitConverter.ToString(d.SignatureMasks[i]));
+ }
+ Assert.Equal(signatureLength, d.SignaturePatterns.Length);
+ Assert.Equal(pattern, BitConverter.ToString(d.SignaturePatterns[0]));
+ if (pattern2 != null)
+ Assert.Equal(pattern2, BitConverter.ToString(d.SignaturePatterns[1]));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Decoders()
+ {
+ Assert.Equal(8, decoders.Count);
+ foreach (DictionaryEntry de in decoders)
+ {
+ string guid = de.Key.ToString();
+ switch (guid)
+ {
+ case "557cf402-1a04-11d3-9a73-0000f81ef32e": // GIF
+ case "557cf403-1a04-11d3-9a73-0000f81ef32e": // EMF
+ case "557cf400-1a04-11d3-9a73-0000f81ef32e": // BMP/DIB/RLE
+ case "557cf401-1a04-11d3-9a73-0000f81ef32e": // JPG,JPEG,JPE,JFIF
+ case "557cf406-1a04-11d3-9a73-0000f81ef32e": // PNG
+ case "557cf407-1a04-11d3-9a73-0000f81ef32e": // ICO
+ case "557cf404-1a04-11d3-9a73-0000f81ef32e": // WMF
+ case "557cf405-1a04-11d3-9a73-0000f81ef32e": // TIF,TIFF
+ break;
+ default:
+ Assert.True(false, "Unknown decoder " + guid);
+ break;
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Encoders()
+ {
+ Assert.Equal(5, encoders.Count);
+ foreach (DictionaryEntry de in encoders)
+ {
+ string guid = de.Key.ToString();
+ switch (guid)
+ {
+ case "557cf402-1a04-11d3-9a73-0000f81ef32e": // GIF
+ case "557cf400-1a04-11d3-9a73-0000f81ef32e": // BMP/DIB/RLE
+ case "557cf401-1a04-11d3-9a73-0000f81ef32e": // JPG,JPEG,JPE,JFIF
+ case "557cf406-1a04-11d3-9a73-0000f81ef32e": // PNG
+ case "557cf405-1a04-11d3-9a73-0000f81ef32e": // TIF,TIFF
+ break;
+ default:
+ Assert.True(false, "Unknown encoder " + guid);
+ break;
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BMPCodec()
+ {
+ Guid g = new Guid("557cf400-1a04-11d3-9a73-0000f81ef32e");
+ Check(GetEncoder(g), GetDecoder(g), ImageFormat.Bmp.Guid,
+ "BMP", null, "*.BMP",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "BMP", "image/bmp", 1, 1, "FF-FF", "42-4D", null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GifCodec()
+ {
+ Guid g = new Guid("557cf402-1a04-11d3-9a73-0000f81ef32e");
+ Check(GetEncoder(g), GetDecoder(g), ImageFormat.Gif.Guid,
+ "GIF", null, "*.GIF",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "GIF", "image/gif", 1, 2, "FF-FF-FF-FF-FF-FF", "47-49-46-38-39-61", "47-49-46-38-37-61");
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void JpegCodec()
+ {
+ Guid g = new Guid("557cf401-1a04-11d3-9a73-0000f81ef32e");
+ Check(GetEncoder(g), GetDecoder(g), ImageFormat.Jpeg.Guid,
+ "JPEG", null, "*.JPG",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "JPEG", "image/jpeg", 1, 1, "FF-FF", "FF-D8", null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PngCodec()
+ {
+ Guid g = new Guid("557cf406-1a04-11d3-9a73-0000f81ef32e");
+ Check(GetEncoder(g), GetDecoder(g), ImageFormat.Png.Guid,
+ "PNG", null, "*.PNG",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "PNG", "image/png", 1, 1, "FF-FF-FF-FF-FF-FF-FF-FF", "89-50-4E-47-0D-0A-1A-0A", null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TiffCodec()
+ {
+ Guid g = new Guid("557cf405-1a04-11d3-9a73-0000f81ef32e");
+ Check(GetEncoder(g), GetDecoder(g), ImageFormat.Tiff.Guid,
+ "TIFF", null, "*.TIF;*.TIFF",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Encoder | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "TIFF", "image/tiff", 1, 2, "FF-FF", "49-49", "4D-4D");
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IconCodec_Encoder()
+ {
+ Guid g = new Guid("557cf407-1a04-11d3-9a73-0000f81ef32e");
+ Assert.Null(GetEncoder(g));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IconCodec_Decoder()
+ {
+ Guid g = new Guid("557cf407-1a04-11d3-9a73-0000f81ef32e");
+ Check(null, GetDecoder(g), ImageFormat.Icon.Guid,
+ "ICO", null, "*.ICO",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "ICO", "image/x-icon", 1, 1, "FF-FF-FF-FF", "00-00-01-00", null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmfCodec_Encoder()
+ {
+ Guid g = new Guid("557cf403-1a04-11d3-9a73-0000f81ef32e");
+ Assert.Null(GetEncoder(g));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmfCodec_Decoder()
+ {
+ Guid g = new Guid("557cf403-1a04-11d3-9a73-0000f81ef32e");
+ Check(null, GetDecoder(g), ImageFormat.Emf.Guid,
+ "EMF", null, "*.EMF",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "EMF", "image/x-emf", 1, 1, "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-FF-FF-FF-FF",
+ "00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-20-45-4D-46", null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WmfCodec_Encoder()
+ {
+ Guid g = new Guid("557cf404-1a04-11d3-9a73-0000f81ef32e");
+ Assert.Null(GetEncoder(g));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void WmfCodec_Decoder()
+ {
+ Guid g = new Guid("557cf404-1a04-11d3-9a73-0000f81ef32e");
+ Check(null, GetDecoder(g), ImageFormat.Wmf.Guid,
+ "WMF", null, "*.WMF",
+ ImageCodecFlags.Builtin | ImageCodecFlags.Decoder | ImageCodecFlags.SupportBitmap,
+ "WMF", "image/x-wmf", 1, 1, "FF-FF-FF-FF", "D7-CD-C6-9A", null);
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing.Printing/PrintingServicesUnixTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing.Printing/PrintingServicesUnixTest.cs
new file mode 100644
index 000000000000..a89de88ba3c6
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing.Printing/PrintingServicesUnixTest.cs
@@ -0,0 +1,112 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// PrintingServicesUnix class unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Printing;
+using System.Runtime.InteropServices;
+using Xunit;
+
+namespace MonoTests.System.Drawing.Printing
+{
+
+ public class PrintingServicesUnixTest
+ {
+ #region Novell Bug #602934
+
+ #region CUPS methods and structs
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct CUPS_DEST
+ {
+ public string Name;
+ public string Instance;
+ public int IsDefault;
+ public int NumOptions;
+ public IntPtr Options;
+ }
+
+ [StructLayout(LayoutKind.Sequential)]
+ struct CUPS_OPTION
+ {
+ public string Name;
+ public string Value;
+ }
+
+ readonly IntPtr CUPS_HTTP_DEFAULT = IntPtr.Zero;
+
+ [DllImport("libcups")]
+ static extern IntPtr cupsGetNamedDest(IntPtr http, string name, string instance);
+
+ [DllImport("libcups")]
+ static extern void cupsFreeDests(int num_dests, IntPtr dests);
+
+ [DllImport("libcups")]
+ static extern void cupsFreeDests(int num_dests, ref CUPS_DEST dests);
+
+ #endregion
+
+ Dictionary GetOptionsOfFirstPrinterThroughCups()
+ {
+ var options = new Dictionary();
+
+ var destPtr = cupsGetNamedDest(CUPS_HTTP_DEFAULT, PrinterSettings.InstalledPrinters[0], null);
+ var dest = (CUPS_DEST)Marshal.PtrToStructure(destPtr, typeof(CUPS_DEST));
+ var optionPtr = dest.Options;
+ int cupsOptionSize = Marshal.SizeOf(typeof(CUPS_OPTION));
+ for (int i = 0; i < dest.NumOptions; i++)
+ {
+ var cupsOption = (CUPS_OPTION)Marshal.PtrToStructure(optionPtr, typeof(CUPS_OPTION));
+ options.Add(cupsOption.Name, cupsOption.Value);
+ optionPtr = (IntPtr)((long)optionPtr + cupsOptionSize);
+ }
+ cupsFreeDests(1, destPtr);
+ return options;
+ }
+
+ [ActiveIssue(20844)]
+ public void Bug602934_PrinterSettingsReturnActualValues()
+ {
+ if (PrinterSettings.InstalledPrinters.Count < 1)
+ Assert.True(false, "Need at least one printer installed.");
+
+ var options = GetOptionsOfFirstPrinterThroughCups();
+
+ var settings = new PrinterSettings() { PrinterName = PrinterSettings.InstalledPrinters[0] };
+ Assert.Equal(options["PageSize"], settings.DefaultPageSettings.PaperSize.PaperName);
+ if (options.ContainsKey("Resolution"))
+ Assert.Equal(options["Resolution"], string.Format("{0}dpi", settings.DefaultPageSettings.PrinterResolution.X));
+ }
+
+ #endregion
+
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/ColorTranslator.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/ColorTranslator.cs
new file mode 100644
index 000000000000..e056545df308
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/ColorTranslator.cs
@@ -0,0 +1,231 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// ColorTranslator class testing unit
+//
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class ColorTranslatorTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_Null()
+ {
+ Assert.Equal(0, ColorTranslator.FromHtml(null).ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_Empty()
+ {
+ Assert.Equal(0, ColorTranslator.FromHtml(String.Empty).ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_KnownValues()
+ {
+ Assert.Equal(SystemColors.Control, ColorTranslator.FromHtml("buttonface"));
+ Assert.Equal(SystemColors.ActiveCaptionText, ColorTranslator.FromHtml("CAPTIONTEXT"));
+ Assert.Equal(SystemColors.ControlDarkDark, ColorTranslator.FromHtml("threedDARKshadow"));
+ Assert.Equal(SystemColors.Desktop, ColorTranslator.FromHtml("background"));
+ Assert.Equal(SystemColors.ControlText, ColorTranslator.FromHtml("ButtonText"));
+ Assert.Equal(SystemColors.Info, ColorTranslator.FromHtml("infobackground"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_Int()
+ {
+ Assert.Equal(-1, ColorTranslator.FromHtml("-1").ToArgb());
+ Assert.Equal(0, ColorTranslator.FromHtml("0").ToArgb());
+ Assert.Equal(1, ColorTranslator.FromHtml("1").ToArgb());
+ }
+
+ [ActiveIssue(20844, TestPlatforms.Any)]
+ public void FromHtml_PoundInt()
+ {
+ Assert.Equal(0, ColorTranslator.FromHtml("#0").ToArgb());
+ Assert.Equal(1, ColorTranslator.FromHtml("#1").ToArgb());
+ Assert.Equal(255, ColorTranslator.FromHtml("#FF").ToArgb());
+ Assert.Equal(-15654349, ColorTranslator.FromHtml("#123").ToArgb());
+ Assert.Equal(-1, ColorTranslator.FromHtml("#FFF").ToArgb());
+ Assert.Equal(65535, ColorTranslator.FromHtml("#FFFF").ToArgb());
+ Assert.Equal(-15584170, ColorTranslator.FromHtml("#123456").ToArgb());
+ Assert.Equal(-1, ColorTranslator.FromHtml("#FFFFFF").ToArgb());
+ Assert.Equal(305419896, ColorTranslator.FromHtml("#12345678").ToArgb());
+ Assert.Equal(-1, ColorTranslator.FromHtml("#FFFFFFFF").ToArgb());
+
+ Assert.Equal(Color.White, ColorTranslator.FromHtml("#FFFFFF"));
+ Assert.Equal(Color.White, ColorTranslator.FromHtml("0xFFFFFF"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_PoundNegative()
+ {
+ Assert.Throws(() => ColorTranslator.FromHtml("#-1"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_PoundTooLarge()
+ {
+ Assert.Throws(() => ColorTranslator.FromHtml("#100000000"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml_Unknown()
+ {
+ Assert.Throws(() => ColorTranslator.FromHtml("unknown-color-test"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromHtml()
+ {
+ Color[] colors = new Color[] {
+Color.Aqua, Color.Black, Color.Blue, Color.Fuchsia, Color.Gray,
+Color.Green, Color.Lime, Color.Maroon, Color.Navy, Color.Olive,
+Color.Purple, Color.Red, Color.Silver, Color.Teal, Color.White,
+Color.Yellow,
+
+SystemColors.ActiveBorder, SystemColors.ActiveCaption,
+SystemColors.Control,
+//SystemColors.ControlLightLight,
+SystemColors.ActiveCaptionText, SystemColors.GrayText,
+//SystemColors.InactiveBorder, SystemColors.InactiveCaption,
+SystemColors.InfoText, SystemColors.Menu,
+SystemColors.ControlDarkDark,
+//SystemColors.ControlText, SystemColors.ControlDark,
+SystemColors.Window,
+SystemColors.AppWorkspace, SystemColors.Desktop,
+//SystemColors.ControlDark,
+SystemColors.ControlText,
+SystemColors.Highlight, SystemColors.HighlightText,
+//SystemColors.InactiveCaptionText,
+SystemColors.Info,
+SystemColors.MenuText, SystemColors.ScrollBar,
+//SystemColors.ControlLight, SystemColors.ControlLightLight
+ };
+ string[] htmlColors = new string[] {
+"Aqua", "Black", "Blue", "Fuchsia", "Gray", "Green",
+"Lime", "Maroon", "Navy", "Olive", "Purple", "Red",
+"Silver", "Teal", "White", "Yellow",
+
+"activeborder", "activecaption", "buttonface",
+//"buhighlight",
+"captiontext", "graytext",
+//"iborder", "Icaption",
+"infotext", "menu", "threeddarkshadow",
+//"thrface", "Threedshadow",
+"window", "appworkspace",
+"background",
+//"bshadow",
+"buttontext", "highlight",
+"highlighttext",
+//"icaptiontext",
+"infobackground",
+"menutext", "scrollbar",
+//"thhighlight", "thlightshadow"
+ };
+
+ for (int i = 0; i < colors.Length; i++)
+ Assert.Equal(colors[i], ColorTranslator.FromHtml(htmlColors[i]));
+ }
+
+ [Fact] // 340917
+ public void FromHtml_LightGrey()
+ {
+ Assert.Equal(Color.LightGray, ColorTranslator.FromHtml(ColorTranslator.ToHtml(Color.LightGray)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromOle()
+ {
+ Assert.Equal(Color.FromArgb(0x10, 0x20, 0x30), ColorTranslator.FromOle(0x302010));
+ Assert.Equal(Color.FromArgb(0xbb, 0x20, 0x30), ColorTranslator.FromOle(unchecked((int)0xee3020bb)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FromWin32()
+ {
+ Assert.Equal(Color.FromArgb(0x10, 0x20, 0x30), ColorTranslator.FromWin32(0x302010));
+ Assert.Equal(Color.FromArgb(0xbb, 0x20, 0x30), ColorTranslator.FromWin32(unchecked((int)0xee3020bb)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ToHtml()
+ {
+ string[] htmlColors = new string[] {
+"activeborder", "activecaption", "captiontext", "appworkspace", "buttonface",
+"buttonshadow", "threeddarkshadow", "buttonface", "buttonhighlight", "buttontext",
+"background", "graytext", "highlight", "highlighttext", "highlight", "inactiveborder",
+"inactivecaption", "inactivecaptiontext", "infobackground", "infotext", "menu",
+"menutext", "scrollbar", "window", "windowframe", "windowtext",
+
+"Transparent", "AliceBlue", "AntiqueWhite", "Aqua", "Aquamarine", "Azure", "Beige",
+"Bisque", "Black", "BlanchedAlmond", "Blue", "BlueViolet", "Brown", "BurlyWood",
+"CadetBlue", "Chartreuse", "Chocolate", "Coral", "CornflowerBlue", "Cornsilk",
+"Crimson", "Cyan", "DarkBlue", "DarkCyan", "DarkGoldenrod", "DarkGray", "DarkGreen",
+"DarkKhaki", "DarkMagenta", "DarkOliveGreen", "DarkOrange", "DarkOrchid", "DarkRed",
+"DarkSalmon", "DarkSeaGreen", "DarkSlateBlue", "DarkSlateGray", "DarkTurquoise", "DarkViolet",
+"DeepPink", "DeepSkyBlue", "DimGray", "DodgerBlue", "Firebrick", "FloralWhite", "ForestGreen",
+"Fuchsia", "Gainsboro", "GhostWhite", "Gold", "Goldenrod", "Gray", "Green", "GreenYellow",
+"Honeydew", "HotPink", "IndianRed", "Indigo", "Ivory", "Khaki", "Lavender", "LavenderBlush",
+"LawnGreen", "LemonChiffon", "LightBlue", "LightCoral", "LightCyan", "LightGoldenrodYellow",
+"LightGrey", "LightGreen", "LightPink", "LightSalmon", "LightSeaGreen", "LightSkyBlue",
+"LightSlateGray", "LightSteelBlue", "LightYellow", "Lime", "LimeGreen", "Linen", "Magenta",
+"Maroon", "MediumAquamarine", "MediumBlue", "MediumOrchid", "MediumPurple", "MediumSeaGreen",
+"MediumSlateBlue", "MediumSpringGreen", "MediumTurquoise", "MediumVioletRed", "MidnightBlue",
+"MintCream", "MistyRose", "Moccasin", "NavajoWhite", "Navy", "OldLace", "Olive", "OliveDrab",
+"Orange", "OrangeRed", "Orchid", "PaleGoldenrod", "PaleGreen", "PaleTurquoise", "PaleVioletRed",
+"PapayaWhip", "PeachPuff", "Peru", "Pink", "Plum", "PowderBlue", "Purple", "Red", "RosyBrown",
+"RoyalBlue", "SaddleBrown", "Salmon", "SandyBrown", "SeaGreen", "SeaShell", "Sienna", "Silver",
+"SkyBlue", "SlateBlue", "SlateGray", "Snow", "SpringGreen", "SteelBlue", "Tan", "Teal",
+"Thistle", "Tomato", "Turquoise", "Violet", "Wheat", "White", "WhiteSmoke", "Yellow", "YellowGreen",
+ };
+
+ for (KnownColor i = KnownColor.ActiveBorder; i <= KnownColor.YellowGreen; i++)
+ Assert.Equal(htmlColors[(int)i - 1], ColorTranslator.ToHtml(Color.FromKnownColor(i)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ToOle()
+ {
+ Assert.Equal(0x302010, ColorTranslator.ToOle(Color.FromArgb(0x10, 0x20, 0x30)));
+ Assert.Equal(unchecked((int)0x3020bb), ColorTranslator.ToOle(Color.FromArgb(0xee, 0xbb, 0x20, 0x30)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ToWin32()
+ {
+ Assert.Equal(0x302010, ColorTranslator.ToWin32(Color.FromArgb(0x10, 0x20, 0x30)));
+ Assert.Equal(unchecked((int)0x3020bb), ColorTranslator.ToWin32(Color.FromArgb(0xee, 0xbb, 0x20, 0x30)));
+ }
+
+ }
+}
+
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/FontFamilyTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/FontFamilyTest.cs
new file mode 100644
index 000000000000..b2d72062c993
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/FontFamilyTest.cs
@@ -0,0 +1,200 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.FontFamily unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Text;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class FontFamilyTest
+ {
+
+ private Bitmap bitmap;
+ private Graphics graphic;
+ private string name;
+
+ public FontFamilyTest()
+ {
+ bitmap = new Bitmap(10, 10);
+ graphic = Graphics.FromImage(bitmap);
+ using (FontFamily ff = new FontFamily(GenericFontFamilies.Monospace))
+ {
+ name = ff.Name;
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_String_Null()
+ {
+ Assert.Throws(() => new FontFamily(null));
+ }
+
+ private void CheckMono(FontFamily ff)
+ {
+ Assert.True(ff.Equals(FontFamily.GenericMonospace));
+ // note: Mono has this behaviour on both 1.1 and 2.0 profiles
+ Assert.Equal(ff.Name.GetHashCode(), ff.GetHashCode());
+ }
+
+ [ActiveIssue(20884)]
+ public void FontFamily_String()
+ {
+ FontFamily ff = new FontFamily(name);
+ CheckMono(ff);
+ FontStyle style = FontStyle.Bold;
+ Assert.Equal(ff.Name, ff.GetName(0));
+ Assert.True((ff.GetCellAscent(style) > 0));
+ Assert.True((ff.GetCellDescent(style) > 0));
+ Assert.True((ff.GetEmHeight(style) > 0));
+ Assert.True((ff.GetLineSpacing(style) > 0));
+ Assert.True(ff.IsStyleAvailable(style));
+ }
+
+ [ActiveIssue(20884, TestPlatforms.Any)]
+ public void FontFamily_String_FontCollection_Null()
+ {
+ FontFamily ff = new FontFamily(name, null);
+ CheckMono(ff);
+ }
+
+ [ActiveIssue(20884, TestPlatforms.Any)]
+ public void FontFamily_String_InstalledFontCollection()
+ {
+ FontFamily ff = new FontFamily(name, new InstalledFontCollection());
+ CheckMono(ff);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_String_PrivateFontCollection()
+ {
+ Assert.Throws(() => new FontFamily(name, new PrivateFontCollection()));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_Monospace()
+ {
+ FontFamily ff = new FontFamily(GenericFontFamilies.Monospace);
+ CheckMono(ff);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_SansSerif()
+ {
+ FontFamily ff = new FontFamily(GenericFontFamilies.SansSerif);
+ Assert.True(ff.Equals(FontFamily.GenericSansSerif));
+ // note: Mono has this behaviour on both 1.1 and 2.0 profiles
+ Assert.Equal(ff.Name.GetHashCode(), ff.GetHashCode());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_Serif()
+ {
+ FontFamily ff = new FontFamily(GenericFontFamilies.Serif);
+ Assert.True(ff.Equals(FontFamily.GenericSerif));
+ // note: Mono has this behaviour on both 1.1 and 2.0 profiles
+ Assert.Equal(ff.Name.GetHashCode(), ff.GetHashCode());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FontFamily_Invalid()
+ {
+ FontFamily ff = new FontFamily((GenericFontFamilies)Int32.MinValue);
+ // default to Monospace
+ Assert.True(ff.Equals(FontFamily.GenericMonospace));
+ CheckMono(ff);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GenericMonospace()
+ {
+ FontFamily ff = FontFamily.GenericMonospace;
+ string ts = ff.ToString();
+ Assert.Equal('[', ts[0]);
+ Assert.True((ts.IndexOf(name) >= 0));
+ Assert.Equal(']', ts[ts.Length - 1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GenericSansSerif()
+ {
+ FontFamily ff = FontFamily.GenericSansSerif;
+ string name = ff.Name;
+ ff.Dispose();
+ Assert.Equal(name, FontFamily.GenericSansSerif.Name);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GenericSerif()
+ {
+ FontFamily ff = FontFamily.GenericSerif;
+ string name = ff.Name;
+ ff.Dispose();
+ Assert.Equal(name, FontFamily.GenericSerif.Name);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetFamilies_Null()
+ {
+#pragma warning disable 618
+ Assert.Throws(() => FontFamily.GetFamilies(null));
+#pragma warning restore 618
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetFamilies()
+ {
+#pragma warning disable 618
+ FontFamily[] ffc = FontFamily.GetFamilies(graphic);
+ Assert.Equal(ffc.Length, FontFamily.Families.Length);
+#pragma warning restore 618
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Double()
+ {
+ FontFamily ff = FontFamily.GenericSerif;
+ ff.Dispose();
+ ff.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_UseAfter()
+ {
+ FontFamily ff = FontFamily.GenericMonospace;
+ ff.Dispose();
+ Assert.Throws(() => { var x = ff.Name; });
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/PenTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/PenTest.cs
new file mode 100644
index 000000000000..6af297eb3219
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/PenTest.cs
@@ -0,0 +1,799 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Pen unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using SC = System.ComponentModel;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class PenTest
+ {
+
+ private Pen default_pen;
+ private CustomLineCap custom_line_cap;
+
+ public PenTest()
+ {
+ default_pen = new Pen(Color.Empty);
+ custom_line_cap = new CustomLineCap(new GraphicsPath(), new GraphicsPath());
+ }
+
+ private void Check(Pen p)
+ {
+ Assert.Equal(PenAlignment.Center, p.Alignment);
+ Assert.Equal(typeof(SolidBrush), p.Brush.GetType());
+ Assert.Equal(Color.Red.ToArgb(), (p.Brush as SolidBrush).Color.ToArgb());
+ Assert.Equal(Color.Red.ToArgb(), p.Color.ToArgb());
+ Assert.Equal(0, p.CompoundArray.Length);
+ Assert.Equal(DashCap.Flat, p.DashCap);
+ Assert.Equal(0, p.DashOffset);
+ Assert.Equal(DashStyle.Solid, p.DashStyle);
+ Assert.Equal(LineCap.Flat, p.EndCap);
+ Assert.Equal(LineJoin.Miter, p.LineJoin);
+ Assert.Equal(10, p.MiterLimit);
+ Assert.Equal(PenType.SolidColor, p.PenType);
+ Assert.Equal(LineCap.Flat, p.StartCap);
+ Assert.True(p.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Color()
+ {
+ using (Pen p = new Pen(Color.Red))
+ {
+ Assert.Equal(1, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Color_Float()
+ {
+ using (Pen p = new Pen(Color.Red, 2.5f))
+ {
+ Assert.Equal(2.5f, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Color_Float_Zero()
+ {
+ using (Pen p = new Pen(Color.Red, 0.0f))
+ {
+ Assert.Equal(0.0f, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Color_Float_Negative()
+ {
+ using (Pen p = new Pen(Color.Red, -2))
+ {
+ Assert.Equal(-2, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Color_Float_MaxValue()
+ {
+ using (Pen p = new Pen(Color.Red, Single.MaxValue))
+ {
+ Assert.Equal(Single.MaxValue, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ Assert.Equal(1, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Null()
+ {
+ Assert.Throws(() => new Pen((Brush)null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Float()
+ {
+ using (Pen p = new Pen(Brushes.Red, 2.5f))
+ {
+ Assert.Equal(2.5f, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Float_Null()
+ {
+ Assert.Throws(() => new Pen((Brush)null, Single.MaxValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Float_Zero()
+ {
+ using (Pen p = new Pen(Brushes.Red, 0.0f))
+ {
+ Assert.Equal(0.0f, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Float_Negative()
+ {
+ using (Pen p = new Pen(Brushes.Red, -2))
+ {
+ Assert.Equal(-2, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_Float_MaxValue()
+ {
+ using (Pen p = new Pen(Brushes.Red, Single.MaxValue))
+ {
+ Assert.Equal(Single.MaxValue, p.Width);
+ Check(p);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Constructor_Brush_DisposeBeforeUse()
+ {
+ using (SolidBrush b = new SolidBrush(Color.Red))
+ {
+ using (Pen p = new Pen(b, 1))
+ {
+ b.Dispose();
+ Check(p);
+ using (Bitmap bmp = new Bitmap(12, 12))
+ {
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ g.DrawLine(p, 1, 1, 10, 10);
+ }
+ }
+ }
+ }
+ }
+
+ private void Check2(Pen p)
+ {
+ Assert.Equal(typeof(SolidBrush), p.Brush.GetType());
+ Assert.Equal(Color.Red.ToArgb(), (p.Brush as SolidBrush).Color.ToArgb());
+ Assert.Equal(Color.Red.ToArgb(), p.Color.ToArgb());
+ Assert.Equal(0, p.CompoundArray.Length);
+ // Assert.Equal (DashCap.Flat, p.DashCap);
+ Assert.Equal(0, p.DashOffset);
+ Assert.Equal(10, p.MiterLimit);
+ Assert.Equal(PenType.SolidColor, p.PenType);
+ Assert.True(p.Transform.IsIdentity);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Alignment()
+ {
+ using (Pen p = new Pen(Brushes.Gold, Single.NegativeInfinity))
+ {
+ foreach (PenAlignment pa in Enum.GetValues(typeof(PenAlignment)))
+ {
+ p.Alignment = pa;
+ Assert.Equal(pa, p.Alignment);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void Alignment_Invalid()
+ {
+ Assert.Throws(() => default_pen.Alignment = (PenAlignment)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Brush_Dispose()
+ {
+ using (Pen p = new Pen(Brushes.Red, 2.5f))
+ {
+ // are we getting the original brush ?
+ Brush b1 = p.Brush;
+ b1.Dispose();
+ Check(p);
+ using (Pen clone = (Pen)p.Clone())
+ {
+ Check(clone);
+ }
+ Assert.False(Object.ReferenceEquals(b1, p.Brush));
+ // nope :)
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Brush_Null()
+ {
+ Assert.Throws(() => default_pen.Brush = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashCap_Valid()
+ {
+ // note: YellowGreen is broken by a destructive test so we can't use it afterward
+ // note: this worked with nunit 2.2 because this test was executed before the destructive one
+ using (Pen p = new Pen(Brushes.Yellow, 0))
+ {
+ foreach (DashCap dc in Enum.GetValues(typeof(DashCap)))
+ {
+ p.DashCap = dc;
+ Assert.Equal(dc, p.DashCap);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void DashCap_Invalid()
+ {
+ Assert.Throws(() => default_pen.DashCap = (DashCap)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashOffset()
+ {
+ using (Pen p = new Pen(Brushes.Transparent, 32))
+ {
+ p.DashOffset = 0;
+ Assert.Equal(0, p.DashOffset);
+ p.DashOffset = Single.MaxValue;
+ Assert.Equal(Single.MaxValue, p.DashOffset);
+ p.DashOffset = Single.MinValue;
+ Assert.Equal(Single.MinValue, p.DashOffset);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashPattern()
+ {
+ using (Pen p = new Pen(Brushes.Tomato, 1.1f))
+ {
+ Assert.Equal(DashStyle.Solid, p.DashStyle);
+ p.DashPattern = new float[1] { 1 };
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(1, p.DashPattern.Length);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashPattern_Empty()
+ {
+ Assert.Throws(() => default_pen.DashPattern = new float[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashStyle_Valid()
+ {
+ using (Pen p = new Pen(Brushes.Silver, Single.PositiveInfinity))
+ {
+ foreach (DashStyle ds in Enum.GetValues(typeof(DashStyle)))
+ {
+ p.DashStyle = ds;
+ Assert.Equal(ds, p.DashStyle);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void DashStyle_Invalid()
+ {
+ Assert.Throws(() => default_pen.DashStyle = (DashStyle)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DashStyle_Custom()
+ {
+ using (Pen p = new Pen(Brushes.Silver, Single.PositiveInfinity))
+ {
+ Assert.Equal(DashStyle.Solid, p.DashStyle);
+ // can't ask for Solid (default) -> OutOfMemoryException
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(1, p.DashPattern.Length);
+ Assert.Equal(1, p.DashPattern[0]);
+
+ p.DashStyle = DashStyle.Dot;
+ Assert.Equal(DashStyle.Dot, p.DashStyle);
+ Assert.Equal(2, p.DashPattern.Length);
+ Assert.Equal(1, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(2, p.DashPattern.Length);
+ Assert.Equal(1, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+
+ p.DashStyle = DashStyle.Dash;
+ Assert.Equal(DashStyle.Dash, p.DashStyle);
+ Assert.Equal(2, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(2, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+
+ p.DashStyle = DashStyle.DashDot;
+ Assert.Equal(DashStyle.DashDot, p.DashStyle);
+ Assert.Equal(4, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(4, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+
+ p.DashStyle = DashStyle.DashDotDot;
+ Assert.Equal(DashStyle.DashDotDot, p.DashStyle);
+ Assert.Equal(6, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(6, p.DashPattern.Length);
+ Assert.Equal(3, p.DashPattern[0]);
+ Assert.Equal(1, p.DashPattern[1]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+ Assert.Equal(1, p.DashPattern[2]);
+ Assert.Equal(1, p.DashPattern[3]);
+
+ // resetting to DashStyle.Solid doesn't throw the OutOfMemoryException
+ // on MS runtime
+ p.DashStyle = DashStyle.Solid;
+ Assert.Equal(DashStyle.Solid, p.DashStyle);
+ Assert.Equal(0, p.DashPattern.Length);
+ p.DashStyle = DashStyle.Custom;
+ Assert.Equal(DashStyle.Custom, p.DashStyle);
+ Assert.Equal(1, p.DashPattern.Length);
+ Assert.Equal(1, p.DashPattern[0]);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EndCap_Valid()
+ {
+ using (Pen p = new Pen(Brushes.Silver, Single.PositiveInfinity))
+ {
+ foreach (LineCap lc in Enum.GetValues(typeof(LineCap)))
+ {
+ p.EndCap = lc;
+ Assert.Equal(lc, p.EndCap);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void EndCap_Invalid()
+ {
+ Assert.Throws(() => default_pen.EndCap = (LineCap)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LineJoin_Valid()
+ {
+ using (Pen p = new Pen(Brushes.Chocolate, Single.NaN))
+ {
+ foreach (LineJoin lj in Enum.GetValues(typeof(LineJoin)))
+ {
+ p.LineJoin = lj;
+ Assert.Equal(lj, p.LineJoin);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void LineJoin_Invalid()
+ {
+ Assert.Throws(() => default_pen.LineJoin = (LineJoin)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MiterLimit()
+ {
+ using (Pen p = new Pen(Brushes.Tan, 1))
+ {
+ p.MiterLimit = Single.MinValue;
+ Assert.Equal(1, p.MiterLimit);
+ p.MiterLimit = 0;
+ Assert.Equal(1, p.MiterLimit);
+ p.MiterLimit = Single.MaxValue;
+ Assert.Equal(Single.MaxValue, p.MiterLimit);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void StartCap_Valid()
+ {
+ using (Pen p = new Pen(Brushes.Silver, Single.PositiveInfinity))
+ {
+ foreach (LineCap lc in Enum.GetValues(typeof(LineCap)))
+ {
+ p.StartCap = lc;
+ Assert.Equal(lc, p.StartCap);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable, Skip = "Internal ArgumentException in System.Drawing")]
+ public void StartCap_Invalid()
+ {
+ Assert.Throws(() => default_pen.StartCap = (LineCap)Int32.MinValue);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Null()
+ {
+ Assert.Throws(() => default_pen.Transform = null);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_NonInvertible()
+ {
+ using (Pen p = new Pen(Brushes.Snow, Single.MaxValue))
+ {
+ Assert.Throws(() => p.Transform = new Matrix(123, 24, 82, 16, 47, 30));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Width()
+ {
+ using (Pen p = new Pen(Brushes.Tan, Single.MinValue))
+ {
+ Assert.Equal(Single.MinValue, p.Width);
+ p.Width = 0;
+ Assert.Equal(0, p.Width);
+ p.Width = Single.MaxValue;
+ Assert.Equal(Single.MaxValue, p.Width);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ using (Pen clone = (Pen)p.Clone())
+ {
+ Check(clone);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose()
+ {
+ Pen p = new Pen(Brushes.Red);
+ p.Dispose();
+ Assert.Throws(() => p.Alignment = PenAlignment.Center);
+ // exception but not an ObjectDisposedException
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetLineCap()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ foreach (LineCap sc in Enum.GetValues(typeof(LineCap)))
+ {
+ foreach (LineCap ec in Enum.GetValues(typeof(LineCap)))
+ {
+ foreach (DashCap dc in Enum.GetValues(typeof(DashCap)))
+ {
+ string s = String.Format("{0}-{1}-{2}", sc, ec, dc);
+ p.SetLineCap(sc, ec, dc);
+ Assert.Equal(sc, p.StartCap);
+ Assert.Equal(ec, p.EndCap);
+ Assert.Equal(dc, p.DashCap);
+ }
+ }
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetLineCap_InvalidStartCap()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.SetLineCap((LineCap)Int32.MinValue, LineCap.Flat, DashCap.Flat);
+ // no exception :( (reported as FDBK50057)
+ Assert.Equal(Int32.MinValue, (int)p.StartCap);
+ Assert.Equal(LineCap.Flat, p.EndCap);
+ Assert.Equal(DashCap.Flat, p.DashCap);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetLineCap_InvalidEndCap()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.SetLineCap(LineCap.Flat, (LineCap)Int32.MinValue, DashCap.Flat);
+ // no exception :( (reported as FDBK50057)
+ Assert.Equal(LineCap.Flat, p.StartCap);
+ Assert.Equal(Int32.MinValue, (int)p.EndCap);
+ Assert.Equal(DashCap.Flat, p.DashCap);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetLineCap_InvalidDashCap()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.SetLineCap(LineCap.Flat, LineCap.Flat, (DashCap)Int32.MinValue);
+ Assert.Equal(LineCap.Flat, p.StartCap);
+ Assert.Equal(LineCap.Flat, p.EndCap);
+ // invalid value was reseted to Flat (reported as FDBK50057)
+ Assert.Equal(DashCap.Flat, p.DashCap);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ //[ExpectedException (typeof (ArgumentNullException))] // reported as FDBK50058
+ public void MultiplyTransform1_Null()
+ {
+ Assert.Throws(() => default_pen.MultiplyTransform(null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ //[ExpectedException (typeof (ArgumentNullException))] // reported as FDBK50058
+ public void MultiplyTransform2_Null()
+ {
+ Assert.Throws(() => default_pen.MultiplyTransform(null, MatrixOrder.Append));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform2_InvalidMatrixOrder()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ Matrix m1 = new Matrix(2, 0.5f, 0.5f, 4, 10, 20);
+ Matrix m2 = new Matrix(1, 0, 0, 1, -50, -30);
+
+ p.Transform = m2;
+ p.MultiplyTransform(m1, (MatrixOrder)Int32.MinValue);
+ // no exception, but which order is it ?
+ Matrix invalid = p.Transform;
+
+ p.Transform = m2;
+ p.MultiplyTransform(m1, MatrixOrder.Append);
+ Assert.True(invalid.Equals(p.Transform));
+
+ p.Transform = m2;
+ p.MultiplyTransform(m1, MatrixOrder.Prepend);
+ Assert.False(invalid.Equals(p.Transform));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiplyTransform_NonInvertible()
+ {
+ using (Matrix noninvertible = new Matrix(123, 24, 82, 16, 47, 30))
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ Assert.Throws(() => p.MultiplyTransform(noninvertible));
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ResetTransform()
+ {
+ using (Matrix m = new Matrix(2, 0, 0, 2, 10, -10))
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.Transform = m;
+ Assert.False(p.Transform.IsIdentity);
+ p.ResetTransform();
+ Assert.True(p.Transform.IsIdentity);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.RotateTransform(90);
+ float[] elements = p.Transform.Elements;
+ Assert.Equal(0, elements[0], 1);
+ Assert.Equal(1, elements[1], 1);
+ Assert.Equal(-1, elements[2], 1);
+ Assert.Equal(0, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ p.RotateTransform(270);
+ Assert.True(p.Transform.IsIdentity);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RotateTransform_InvalidOrder()
+ {
+ Assert.Throws(() => default_pen.RotateTransform(720, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.ScaleTransform(2, 4);
+ float[] elements = p.Transform.Elements;
+ Assert.Equal(2, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(4, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+
+ p.ScaleTransform(0.5f, 0.25f);
+ Assert.True(p.Transform.IsIdentity);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_MaxMin()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.ScaleTransform(Single.MaxValue, Single.MinValue);
+ float[] elements = p.Transform.Elements;
+ Assert.Equal(Single.MaxValue, elements[0]);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(Single.MinValue, elements[3]);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void ScaleTransform_InvalidOrder()
+ {
+ Assert.Throws(() => default_pen.ScaleTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ p.TranslateTransform(1, 1);
+ float[] elements = p.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(1, elements[4], 1);
+ Assert.Equal(1, elements[5], 1);
+
+ p.TranslateTransform(-1, -1);
+ elements = p.Transform.Elements;
+ Assert.Equal(1, elements[0], 1);
+ Assert.Equal(0, elements[1], 1);
+ Assert.Equal(0, elements[2], 1);
+ Assert.Equal(1, elements[3], 1);
+ Assert.Equal(0, elements[4], 1);
+ Assert.Equal(0, elements[5], 1);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TranslateTransform_InvalidOrder()
+ {
+ Assert.Throws(() => default_pen.TranslateTransform(1, 1, (MatrixOrder)Int32.MinValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transform_Operations()
+ {
+ using (Pen p = new Pen(Brushes.Red))
+ {
+ Matrix clone = p.Transform.Clone();
+ Matrix mul = clone.Clone();
+
+ clone.Multiply(mul, MatrixOrder.Append);
+ p.MultiplyTransform(mul, MatrixOrder.Append);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Multiply(mul, MatrixOrder.Prepend);
+ p.MultiplyTransform(mul, MatrixOrder.Prepend);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Append);
+ p.RotateTransform(45, MatrixOrder.Append);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Rotate(45, MatrixOrder.Prepend);
+ p.RotateTransform(45, MatrixOrder.Prepend);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Append);
+ p.ScaleTransform(0.25f, 2, MatrixOrder.Append);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Scale(0.25f, 2, MatrixOrder.Prepend);
+ p.ScaleTransform(0.25f, 2, MatrixOrder.Prepend);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Translate(10, 20, MatrixOrder.Append);
+ p.TranslateTransform(10, 20, MatrixOrder.Append);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Translate(30, 40, MatrixOrder.Prepend);
+ p.TranslateTransform(30, 40, MatrixOrder.Prepend);
+ Assert.Equal(p.Transform, clone);
+
+ clone.Reset();
+ p.ResetTransform();
+ Assert.Equal(p.Transform, clone);
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/RegionDataTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/RegionDataTest.cs
new file mode 100644
index 000000000000..9ca378d96630
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/RegionDataTest.cs
@@ -0,0 +1,141 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.RegionData unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class RegionDataTest
+ {
+
+ private Bitmap bitmap;
+ private Graphics graphic;
+ private GraphicsPath sp1;
+ private GraphicsPath sp2;
+
+ public RegionDataTest()
+ {
+ bitmap = new Bitmap(10, 10);
+ graphic = Graphics.FromImage(bitmap);
+
+ sp1 = new GraphicsPath();
+ sp1.AddPolygon(new Point[4] { new Point(0, 0), new Point(3, 0), new Point(3, 3), new Point(0, 3) });
+
+ sp2 = new GraphicsPath();
+ sp2.AddPolygon(new Point[4] { new Point(2, 2), new Point(5, 2), new Point(5, 5), new Point(2, 5) });
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RegionData_Null()
+ {
+ RegionData data = new Region().GetRegionData();
+ data.Data = null;
+ Assert.Null(data.Data);
+ Assert.Throws(() => new Region(data));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void RegionData_EmptyData()
+ {
+ RegionData data = new Region().GetRegionData();
+ data.Data = new byte[0];
+ Assert.Equal(0, data.Data.Length);
+ try
+ {
+ new Region(data);
+ }
+ catch (ExternalException)
+ {
+ // MS
+ }
+ catch (ArgumentException)
+ {
+ // Mono
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmptyRegion()
+ {
+ // note: an empty region is (for libgdiplus) a rectangular based region
+ Region empty = new Region();
+ RegionData data = empty.GetRegionData();
+ Assert.NotNull(data.Data);
+ Region region = new Region(data);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void PathRegion()
+ {
+ GraphicsPath path = new GraphicsPath();
+ path.AddCurve(new Point[2] { new Point(1, 1), new Point(2, 2) });
+ Region r = new Region(path);
+ RegionData data = r.GetRegionData();
+ Assert.NotNull(data.Data);
+ Region region = new Region(data);
+ Assert.True(r.GetBounds(graphic).Equals(region.GetBounds(graphic)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CombinedPathRegion()
+ {
+ // note: seems identical to PathRegion but it test another code path inside libgdiplus
+ Region r = new Region(sp1);
+ r.Xor(sp2);
+ RegionData data = r.GetRegionData();
+ Assert.NotNull(data.Data);
+ Region region = new Region(data);
+ Assert.True(r.GetBounds(graphic).Equals(region.GetBounds(graphic)));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MultiCombinedPathRegion()
+ {
+ // note: seems identical to PathRegion but it test another code path inside libgdiplus
+ Region r1 = new Region(sp1);
+ r1.Xor(sp2);
+ Region r2 = new Region(sp2);
+ r2.Complement(sp1);
+
+ Region r = r1.Clone();
+ r.Union(r2);
+ RegionData data = r.GetRegionData();
+ Assert.NotNull(data.Data);
+ Region region = new Region(data);
+ Assert.True(r.GetBounds(graphic).Equals(region.GetBounds(graphic)));
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/RegionNonRectTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/RegionNonRectTest.cs
new file mode 100644
index 000000000000..4aecbe28401b
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/RegionNonRectTest.cs
@@ -0,0 +1,727 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.Region non-rectangular unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing.Imaging;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ /* NOTE: General tests and rectangular region tests are located in TestRegion.cs */
+ /* Here we exclusively tests non-rectangular (GraphicsPath based) regions. */
+
+ public class RegionNonRectTest
+ {
+
+ private Bitmap bitmap;
+ private Graphics graphic;
+ private Matrix matrix;
+ private GraphicsPath sp1, sp2, sp3, sp4;
+
+ public RegionNonRectTest()
+ {
+ bitmap = new Bitmap(10, 10);
+ graphic = Graphics.FromImage(bitmap);
+ matrix = new Matrix();
+
+ sp1 = new GraphicsPath();
+ sp1.AddPolygon(new Point[4] { new Point(0, 0), new Point(3, 0), new Point(3, 3), new Point(0, 3) });
+
+ sp2 = new GraphicsPath();
+ sp2.AddPolygon(new Point[4] { new Point(2, 2), new Point(5, 2), new Point(5, 5), new Point(2, 5) });
+
+ sp3 = new GraphicsPath();
+ sp3.AddPolygon(new Point[4] { new Point(6, 0), new Point(9, 0), new Point(9, 3), new Point(6, 3) });
+
+ sp4 = new GraphicsPath();
+ sp4.AddPolygon(new Point[4] { new Point(8, 0), new Point(11, 0), new Point(11, 3), new Point(8, 3) });
+ }
+
+ // a region with an "empty ctor" graphic path is "empty" (i.e. not infinite)
+ private void CheckEmpty(string prefix, Region region)
+ {
+ Assert.True(region.IsEmpty(graphic), prefix + "IsEmpty");
+ Assert.False(region.IsInfinite(graphic), prefix + "graphic");
+
+ RectangleF rect = region.GetBounds(graphic);
+ Assert.Equal(0f, rect.X);
+ Assert.Equal(0f, rect.Y);
+ Assert.Equal(0f, rect.Width);
+ Assert.Equal(0f, rect.Height);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Region_Ctor_GraphicsPath_Empty()
+ {
+ Region region = new Region(new GraphicsPath());
+ CheckEmpty("GraphicsPath.", region);
+
+ Region clone = region.Clone();
+ CheckEmpty("Clone.", region);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Region_Ctor_GraphicsPath()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Region region = new Region(gp);
+ CheckEmpty("GraphicsPath.", region);
+
+ Region clone = region.Clone();
+ CheckEmpty("Clone.", region);
+ }
+
+ private void CheckInfiniteBounds(GraphicsPath path)
+ {
+ RectangleF rect = path.GetBounds();
+ Assert.Equal(-4194304f, rect.X);
+ Assert.Equal(-4194304f, rect.Y);
+ Assert.Equal(8388608f, rect.Width);
+ Assert.Equal(8388608f, rect.Height);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Region_Curve_IsInfinite()
+ {
+ Point[] points = new Point[2] { new Point(-4194304, -4194304), new Point(4194304, 4194304) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(points);
+ CheckInfiniteBounds(gp);
+
+ Region region = new Region(gp);
+ Assert.False(region.IsInfinite(graphic));
+ // note: infinity isn't based on the bounds
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Curve_GetRegionScans()
+ {
+ Point[] points = new Point[2] { new Point(-4194304, -4194304), new Point(4194304, 4194304) };
+ GraphicsPath gp = new GraphicsPath();
+ gp.AddCurve(points);
+ Region region = new Region(gp);
+ // too big, returns 0
+ Assert.Equal(0, region.GetRegionScans(matrix).Length);
+ }
+
+ private void DisplaySmallRegion(Region region, int ox, int oy, int width, int height)
+ {
+ for (int y = oy; y < height - 1; y++)
+ {
+ for (int x = ox; x < width - 1; x++)
+ {
+ if (region.IsVisible(x, y))
+ Console.Write("X");
+ else
+ Console.Write(".");
+ }
+ Console.WriteLine();
+ }
+ }
+
+ private void DisplaySmallRegion(Region region, int width, int height)
+ {
+ DisplaySmallRegion(region, -1, -1, width, height);
+ }
+
+
+ private void CompareSmallRegion(Region region, bool[] expected, int ox, int oy, int width, int height)
+ {
+ int p = 0;
+ for (int y = oy; y < height + oy; y++)
+ {
+ for (int x = ox; x < width + ox; x++)
+ {
+ Assert.Equal(expected[p], region.IsVisible(x, y));
+ p++;
+ }
+ }
+ }
+
+ private void CompareSmallRegion(Region region, bool[] expected, int width, int height)
+ {
+ CompareSmallRegion(region, expected, -1, -1, width, height);
+ }
+
+ private void CheckRectF(string msg, int x, int y, int w, int h, RectangleF rect)
+ {
+ Assert.Equal(x, rect.X);
+ Assert.Equal(y, rect.Y);
+ Assert.Equal(w, rect.Width);
+ Assert.Equal(h, rect.Height);
+ }
+
+ static bool[] sunion = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, true, true, false, // .XXXXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallUnion1()
+ {
+ Region region = new Region(sp1);
+ region.Union(sp2);
+ CompareSmallRegion(region, sunion, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(3, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 5, 1, scans[1]);
+ CheckRectF("[2]", 2, 3, 3, 2, scans[2]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallUnion2()
+ {
+ Region region = new Region(sp2);
+ region.Union(sp1);
+ CompareSmallRegion(region, sunion, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(3, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 5, 1, scans[1]);
+ CheckRectF("[2]", 2, 3, 3, 2, scans[2]);
+ }
+
+ static bool[] self1 = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, false, false, false, // .XXX...
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallUnion_Self1()
+ {
+ Region region = new Region(sp1);
+ region.Union(sp1);
+ CompareSmallRegion(region, self1, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 3, scans[0]);
+ }
+
+ static bool[] self2 = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallUnion_Self2()
+ {
+ Region region = new Region(sp2);
+ region.Union(sp2);
+ CompareSmallRegion(region, self2, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 2, 2, 3, 3, scans[0]);
+ }
+
+ static bool[] sintersection = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, true, false, false, false, // ...X...
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallIntersection1()
+ {
+ Region region = new Region(sp1);
+ region.Intersect(sp2);
+ CompareSmallRegion(region, sintersection, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 2, 2, 1, 1, scans[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallIntersection2()
+ {
+ Region region = new Region(sp2);
+ region.Intersect(sp1);
+ CompareSmallRegion(region, sintersection, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 2, 2, 1, 1, scans[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallIntersection_Self1()
+ {
+ Region region = new Region(sp1);
+ region.Intersect(sp1);
+ CompareSmallRegion(region, self1, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 3, scans[0]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallIntersection_Self2()
+ {
+ Region region = new Region(sp2);
+ region.Intersect(sp2);
+ CompareSmallRegion(region, self2, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(1, scans.Length);
+ CheckRectF("[0]", 2, 2, 3, 3, scans[0]);
+ }
+
+ static bool[] sexclude1 = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, false, false, false, false, // .XX....
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallExclude1()
+ {
+ Region region = new Region(sp1);
+ region.Exclude(sp2);
+ CompareSmallRegion(region, sexclude1, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(2, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 2, 1, scans[1]);
+ }
+
+ static bool[] sexclude2 = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, true, true, false, // ....XX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallExclude2()
+ {
+ Region region = new Region(sp2);
+ region.Exclude(sp1);
+ CompareSmallRegion(region, sexclude2, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(2, scans.Length);
+ CheckRectF("[0]", 3, 2, 2, 1, scans[0]);
+ CheckRectF("[1]", 2, 3, 3, 2, scans[1]);
+ }
+
+ static bool[] sempty = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallExclude_Self1()
+ {
+ Region region = new Region(sp1);
+ region.Exclude(sp1);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallExclude_Self2()
+ {
+ Region region = new Region(sp2);
+ region.Exclude(sp2);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallComplement1()
+ {
+ Region region = new Region(sp1);
+ region.Complement(sp2);
+ CompareSmallRegion(region, sexclude2, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(2, scans.Length);
+ CheckRectF("[0]", 3, 2, 2, 1, scans[0]);
+ CheckRectF("[1]", 2, 3, 3, 2, scans[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallComplement2()
+ {
+ Region region = new Region(sp2);
+ region.Complement(sp1);
+ CompareSmallRegion(region, sexclude1, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(2, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 2, 1, scans[1]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallComplement_Self1()
+ {
+ Region region = new Region(sp1);
+ region.Complement(sp1);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallComplement_Self2()
+ {
+ Region region = new Region(sp2);
+ region.Complement(sp2);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ static bool[] sxor = new bool[49] {
+ false, false, false, false, false, false, false, // .......
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, true, false, false, false, // .XXX...
+ false, true, true, false, true, true, false, // .XX.XX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, true, true, true, false, // ...XXX.
+ false, false, false, false, false, false, false, // .......
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallXor1()
+ {
+ Region region = new Region(sp1);
+ region.Xor(sp2);
+ CompareSmallRegion(region, sxor, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(4, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 2, 1, scans[1]);
+ CheckRectF("[2]", 3, 2, 2, 1, scans[2]);
+ CheckRectF("[3]", 2, 3, 3, 2, scans[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallXor2()
+ {
+ Region region = new Region(sp2);
+ region.Xor(sp1);
+ CompareSmallRegion(region, sxor, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(4, scans.Length);
+ CheckRectF("[0]", 0, 0, 3, 2, scans[0]);
+ CheckRectF("[1]", 0, 2, 2, 1, scans[1]);
+ CheckRectF("[2]", 3, 2, 2, 1, scans[2]);
+ CheckRectF("[3]", 2, 3, 3, 2, scans[3]);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallXor_Self1()
+ {
+ Region region = new Region(sp1);
+ region.Xor(sp1);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SmallXor_Self2()
+ {
+ Region region = new Region(sp2);
+ region.Xor(sp2);
+ CompareSmallRegion(region, sempty, 7, 7);
+
+ RectangleF[] scans = region.GetRegionScans(matrix);
+ Assert.Equal(0, scans.Length);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void NegativeXor()
+ {
+ GraphicsPath neg = new GraphicsPath();
+ // identical result (matrix) of XOR but we're using negative coordinates
+ neg.AddPolygon(new Point[4] { new Point(-2, -2), new Point(1, -2), new Point(1, 1), new Point(-2, 1) });
+
+ Region region = new Region(sp1);
+ region.Xor(neg);
+ CompareSmallRegion(region, sxor, -3, -3, 7, 7);
+ }
+
+ static bool[] ni_union = new bool[55] {
+ false, false, false, false, false, false, false, false, false, false, false, // ...........
+ false, true, true, true, false, false, false, true, true, true, false, // .XXX...XXX.
+ false, true, true, true, false, false, false, true, true, true, false, // .XXX...XXX.
+ false, true, true, true, false, false, false, true, true, true, false, // .XXX...XXX.
+ false, false, false, false, false, false, false, false, false, false, false, // ...........
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void UnionWithoutIntersection()
+ {
+ Region region = new Region(sp1);
+ region.Union(sp3);
+ CompareSmallRegion(region, ni_union, 11, 5);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: both region are considered inside as intersecting rectangle because
+ // part of them co-exists in the same 8x8 bitmap. Full algorithm apply but results
+ // in an empty bitmap
+ public void IntersectionWithoutIntersection()
+ {
+ Region region = new Region(sp1);
+ region.Intersect(sp3);
+ CompareSmallRegion(region, sempty, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: no intersection results in an empty bitmap (optimization)
+ public void IntersectionWithoutIntersection_Large()
+ {
+ Region region = new Region(sp1);
+ region.Intersect(sp4);
+ CompareSmallRegion(region, sempty, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: both region are considered inside as intersecting rectangle because
+ // part of them co-exists in the same 8x8 bitmap. Full algorithm apply but results
+ // as a copy of sp1
+ public void ExcludeWithoutIntersection()
+ {
+ Region region = new Region(sp1);
+ region.Exclude(sp3);
+ CompareSmallRegion(region, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: no intersection results in a clone of sp1 (optimization)
+ public void ExcludeWithoutIntersection_Large()
+ {
+ Region region = new Region(sp1);
+ region.Exclude(sp4);
+ CompareSmallRegion(region, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: both region are considered inside as intersecting rectangle because
+ // part of them co-exists in the same 8x8 bitmap. Full algorithm apply but results
+ // as a copy of sp1
+ public void ComplementWithoutIntersection()
+ {
+ Region region = new Region(sp3);
+ region.Complement(sp1);
+ CompareSmallRegion(region, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: no intersection results in a clone of sp1 (optimization)
+ public void ComplementWithoutIntersection_Large()
+ {
+ Region region = new Region(sp4);
+ region.Complement(sp1);
+ CompareSmallRegion(region, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: both region are considered inside as intersecting rectangle because
+ // part of them co-exists in the same 8x8 bitmap.
+ public void XorWithoutIntersection()
+ {
+ Region region = new Region(sp1);
+ region.Xor(sp3);
+ CompareSmallRegion(region, ni_union, 11, 5);
+ }
+
+ static bool[] ni_xor = new bool[65] {
+ false, false, false, false, false, false, false, false, false, false, false, false, false, // .............
+ false, true, true, true, false, false, false, false, false, true, true, true, false, // .XXX.....XXX.
+ false, true, true, true, false, false, false, false, false, true, true, true, false, // .XXX.....XXX.
+ false, true, true, true, false, false, false, false, false, true, true, true, false, // .XXX.....XXX.
+ false, false, false, false, false, false, false, false, false, false, false, false, false, // .............
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ // libgdiplus: both region aren't considered as an intersection because they do
+ // not co-exists in the same 8x8 bitmap. In this case the xor function calls the
+ // union code (optimization).
+ public void XorWithoutIntersection_Large()
+ {
+ Region region = new Region(sp1);
+ region.Xor(sp4);
+ CompareSmallRegion(region, ni_xor, 13, 5);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void IsEqual()
+ {
+ Region r1 = new Region(sp1);
+ Region r2 = new Region(sp2);
+ Region r3 = new Region(sp3);
+ Region r4 = new Region(sp4);
+ // with self
+ Assert.True(r1.Equals(r1, graphic));
+ Assert.True(r2.Equals(r2, graphic));
+ Assert.True(r3.Equals(r3, graphic));
+ Assert.True(r4.Equals(r4, graphic));
+ // with a different
+ Assert.False(r1.Equals(r4, graphic));
+ Assert.False(r2.Equals(r3, graphic));
+ Assert.False(r3.Equals(r2, graphic));
+ Assert.False(r4.Equals(r1, graphic));
+ // with same (not self)
+ Region r5 = r1.Clone();
+ r1.Exclude(r4);
+ Assert.True(r1.Equals(r5, graphic));
+ Assert.True(r5.Equals(r1, graphic));
+ Assert.False(r5.Equals(r4, graphic));
+ Assert.False(r4.Equals(r5, graphic));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Translate_Int()
+ {
+ Region r1 = new Region(sp1);
+ Region r2 = new Region(sp2);
+ r2.Translate(-2, -2);
+ r1.Intersect(r2);
+ CompareSmallRegion(r1, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Translate_Float()
+ {
+ Region r1 = new Region(sp1);
+ Region r2 = new Region(sp2);
+ r2.Translate(-2.0f, -2.0f);
+ r1.Intersect(r2);
+ CompareSmallRegion(r1, self1, 7, 7);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmptyPathWithInfiniteRegion()
+ {
+ GraphicsPath gp = new GraphicsPath();
+ Region region = new Region();
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Union(gp);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Xor(gp);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Exclude(gp);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Intersect(gp);
+ Assert.True(region.IsEmpty(graphic));
+
+ region.MakeInfinite();
+ region.Complement(gp);
+ Assert.True(region.IsEmpty(graphic));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void EmptyRegionWithInfiniteRegion()
+ {
+ Region empty = new Region();
+ empty.MakeEmpty();
+ Assert.True(empty.IsEmpty(graphic));
+
+ Region region = new Region();
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Union(empty);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Xor(empty);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Exclude(empty);
+ Assert.True(region.IsInfinite(graphic));
+
+ region.Intersect(empty);
+ Assert.True(region.IsEmpty(graphic));
+
+ region.MakeInfinite();
+ region.Complement(empty);
+ Assert.True(region.IsEmpty(graphic));
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/SolidBrushTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/SolidBrushTest.cs
new file mode 100644
index 000000000000..c9b4970a7a04
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/SolidBrushTest.cs
@@ -0,0 +1,141 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// System.Drawing.SolidBrush unit tests
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Security.Permissions;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class SolidBrushTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Transparent()
+ {
+ SolidBrush sb = new SolidBrush(Color.Transparent);
+ Assert.Equal(Color.Transparent, sb.Color);
+ sb.Color = Color.Empty;
+ SolidBrush clone = (SolidBrush)sb.Clone();
+ sb.Dispose();
+ Assert.Equal(Color.Empty.ToArgb(), clone.Color.ToArgb());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Color()
+ {
+ SolidBrush sb = new SolidBrush(Color.Transparent);
+ sb.Dispose();
+ Assert.Equal(Color.Transparent, sb.Color);
+ // no exception - the call probably doesn't get to gdi+
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Clone()
+ {
+ SolidBrush sb = new SolidBrush(Color.Transparent);
+ sb.Dispose();
+ Assert.Throws(() => sb.Clone());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Dispose()
+ {
+ SolidBrush sb = new SolidBrush(Color.Transparent);
+ sb.Dispose();
+ sb.Dispose();
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FillRectangle()
+ {
+ using (Bitmap bmp = new Bitmap(10, 10))
+ {
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ SolidBrush sb = new SolidBrush(Color.Red);
+ g.FillRectangle(sb, 0, 0, 9, 9);
+ sb.Color = Color.Blue;
+ g.FillRectangle(sb, 4, 4, 5, 5);
+ }
+ Assert.Equal(Color.Red.ToArgb(), bmp.GetPixel(0, 0).ToArgb());
+ Assert.Equal(Color.Blue.ToArgb(), bmp.GetPixel(8, 8).ToArgb());
+ Assert.Equal(0, bmp.GetPixel(9, 9).ToArgb());
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DrawLine()
+ {
+ using (Bitmap bmp = new Bitmap(10, 10))
+ {
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ SolidBrush sb = new SolidBrush(Color.Red);
+ Pen p = new Pen(sb);
+ g.DrawLine(p, 0, 0, 9, 9);
+ sb.Color = Color.Blue;
+ g.DrawLine(p, 8, 8, 4, 4); // pen is still red
+ }
+ Assert.Equal(Color.Red.ToArgb(), bmp.GetPixel(0, 0).ToArgb());
+ Assert.Equal(Color.Red.ToArgb(), bmp.GetPixel(8, 8).ToArgb());
+ Assert.Equal(Color.Red.ToArgb(), bmp.GetPixel(9, 9).ToArgb()); // include end point
+ }
+ using (Bitmap bmp = new Bitmap(10, 10))
+ {
+ using (Graphics g = Graphics.FromImage(bmp))
+ {
+ SolidBrush sb = new SolidBrush(Color.Red);
+ Pen p = new Pen(sb);
+ g.DrawLine(p, float.NaN, float.NaN, 9, 9);
+ }
+ Assert.NotEqual(Color.Red.ToArgb(), bmp.GetPixel(0, 0).ToArgb());
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone()
+ {
+ using (SolidBrush sb = new SolidBrush(Color.Transparent))
+ {
+ // we still get a "named" color
+ Assert.Equal(Color.Transparent, sb.Color);
+ using (SolidBrush clone = (SolidBrush)sb.Clone())
+ {
+ // but not after cloning the brush
+ Assert.False(Color.Transparent.Equals(clone.Color));
+ Assert.Equal(Color.Transparent.ToArgb(), clone.Color.ToArgb());
+ }
+ }
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/SystemFontsTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/SystemFontsTest.cs
new file mode 100644
index 000000000000..2a2c5f179808
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/SystemFontsTest.cs
@@ -0,0 +1,122 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Tests for System.Drawing.SystemFontsTest
+//
+// Authors:
+// Gert Driesen
+// Sebastien Pouliot
+//
+// Copyright (C) 2006-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+
+using System;
+using System.Drawing;
+
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class SystemFontsTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DefaultFont()
+ {
+ Font f = SystemFonts.DefaultFont;
+ Assert.False(f.Bold);
+
+ Assert.Equal(true, f.IsSystemFont);
+ Assert.False(f.Italic);
+ Assert.Equal(8.25, f.Size, 2);
+ Assert.Equal(8.25, f.SizeInPoints, 2);
+ Assert.False(f.Strikeout);
+ Assert.False(f.Underline);
+ Assert.Equal(GraphicsUnit.Point, f.Unit);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SystemFontName()
+ {
+ Assert.Equal("CaptionFont", SystemFonts.CaptionFont.SystemFontName);
+ Assert.Equal("DefaultFont", SystemFonts.DefaultFont.SystemFontName);
+ Assert.Equal("DialogFont", SystemFonts.DialogFont.SystemFontName);
+ Assert.Equal("IconTitleFont", SystemFonts.IconTitleFont.SystemFontName);
+ Assert.Equal("MenuFont", SystemFonts.MenuFont.SystemFontName);
+ Assert.Equal("MessageBoxFont", SystemFonts.MessageBoxFont.SystemFontName);
+ Assert.Equal("SmallCaptionFont", SystemFonts.SmallCaptionFont.SystemFontName);
+ Assert.Equal("StatusFont", SystemFonts.StatusFont.SystemFontName);
+ }
+
+ [ConditionalFact(Helpers.RecentGdiplusIsAvailable)]
+ public void GetFontByName()
+ {
+ Assert.Equal("CaptionFont", SystemFonts.GetFontByName("CaptionFont").SystemFontName);
+ Assert.Equal("DefaultFont", SystemFonts.GetFontByName("DefaultFont").SystemFontName);
+ Assert.Equal("DialogFont", SystemFonts.GetFontByName("DialogFont").SystemFontName);
+ Assert.Equal("IconTitleFont", SystemFonts.GetFontByName("IconTitleFont").SystemFontName);
+ Assert.Equal("MenuFont", SystemFonts.GetFontByName("MenuFont").SystemFontName);
+ Assert.Equal("MessageBoxFont", SystemFonts.GetFontByName("MessageBoxFont").SystemFontName);
+ Assert.Equal("SmallCaptionFont", SystemFonts.GetFontByName("SmallCaptionFont").SystemFontName);
+ Assert.Equal("StatusFont", SystemFonts.GetFontByName("StatusFont").SystemFontName);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void GetFontByName_Invalid()
+ {
+ Assert.Null(SystemFonts.GetFontByName(null));
+ Assert.Null(SystemFonts.GetFontByName(String.Empty));
+ Assert.Null(SystemFonts.GetFontByName("defaultfont"));
+ Assert.Null(SystemFonts.GetFontByName("DEFAULTFONT"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Same()
+ {
+ Font f1 = SystemFonts.CaptionFont;
+ Font f2 = SystemFonts.CaptionFont;
+ Assert.False(Object.ReferenceEquals(f1, f2));
+ f2 = SystemFonts.GetFontByName("CaptionFont");
+ Assert.False(Object.ReferenceEquals(f1, f2));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Instance()
+ {
+ Font f1 = SystemFonts.CaptionFont;
+ float height = f1.GetHeight(72f);
+ f1.Dispose();
+ Assert.Throws(() => f1.GetHeight(72f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Property()
+ {
+ float height = SystemFonts.CaptionFont.GetHeight(72f);
+ SystemFonts.CaptionFont.Dispose();
+ Assert.Equal(height, SystemFonts.CaptionFont.GetHeight(72f));
+ }
+ }
+}
+
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/SystemIconsTest.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/SystemIconsTest.cs
new file mode 100644
index 000000000000..03c5b961b3af
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/SystemIconsTest.cs
@@ -0,0 +1,76 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Tests for System.Drawing.SystemIconsTest.cs
+//
+// Authors:
+// Sebastien Pouliot
+//
+// Copyright (C) 2006 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using Xunit;
+using System;
+using System.Drawing;
+using System.Security.Permissions;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class SystemIconsTest
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Same()
+ {
+ // SystemIcons always return the same icon
+ Assert.True(Object.ReferenceEquals(SystemIcons.Application, SystemIcons.Application));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_SystemIcons()
+ {
+ // SystemIcons icon's can't be disposed
+ SystemIcons.Application.Dispose();
+ Assert.NotNull(SystemIcons.Application.ToBitmap());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Dispose_Indirect()
+ {
+ // SystemIcons icon's can't be disposed
+ Icon app = SystemIcons.Application;
+ app.Dispose();
+ Assert.NotNull(app.ToBitmap());
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone_Dispose()
+ {
+ // Clones of SystemIcons icon's can be disposed
+ Icon app = SystemIcons.Application;
+ Icon clone = (Icon)app.Clone();
+ clone.Dispose();
+ Assert.Throws(() => clone.ToBitmap());
+ }
+ }
+}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/TestBitmap.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/TestBitmap.cs
new file mode 100644
index 000000000000..ccb3cb9b1957
--- /dev/null
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/TestBitmap.cs
@@ -0,0 +1,1762 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// See the LICENSE file in the project root for more information.
+//
+// Bitmap class testing unit
+//
+// Authors:
+// Jordi Mas i Hernà ndez (jmas@softcatala.org>
+// Jonathan Gilbert
+// Sebastien Pouliot
+//
+// (C) 2004 Ximian, Inc. http://www.ximian.com
+// Copyright (C) 2004,2006-2007 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+
+using System;
+using System.Drawing;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Security.Cryptography;
+using System.Security.Permissions;
+using System.Text;
+using System.Xml.Serialization;
+using Xunit;
+
+namespace MonoTests.System.Drawing
+{
+
+ public class TestBitmap
+ {
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void TestPixels()
+ {
+ // Tests GetSetPixel/SetPixel
+ Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb);
+ bmp.SetPixel(0, 0, Color.FromArgb(255, 128, 128, 128));
+ Color color = bmp.GetPixel(0, 0);
+
+ Assert.Equal(Color.FromArgb(255, 128, 128, 128), color);
+
+ bmp.SetPixel(99, 99, Color.FromArgb(255, 255, 0, 155));
+ Color color2 = bmp.GetPixel(99, 99);
+ Assert.Equal(Color.FromArgb(255, 255, 0, 155), color2);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_32_32_NonIndexedWrite()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format32bppRgb, data.PixelFormat);
+ Assert.Equal(400, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_32_24_NonIndexedWrite()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat);
+ Assert.Equal(300, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_24_24_NonIndexedWrite()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format24bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat);
+ Assert.Equal(300, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_24_32_NonIndexedWrite()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format24bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format32bppRgb, data.PixelFormat);
+ Assert.Equal(400, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ActiveIssue(20884)]
+ public void LockBits_IndexedWrite_NonIndexed()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format8bppIndexed))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ Assert.Throws(() => bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
+ }
+ }
+
+ [ActiveIssue(20884)]
+ public void LockBits_NonIndexedWrite_ToIndexed()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ BitmapData bd = new BitmapData();
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ Assert.Throws(() => bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed, bd));
+
+ // test to see if there's a leak or not in this case
+ Assert.Equal(IntPtr.Zero, bd.Scan0);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_IndexedWrite_SameIndexedFormat()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format8bppIndexed))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ BitmapData data = bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format8bppIndexed, data.PixelFormat);
+ Assert.Equal(100, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_ImageLockMode_Invalid()
+ {
+ using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format24bppRgb))
+ {
+ Rectangle r = new Rectangle(4, 4, 4, 4);
+ BitmapData data = bmp.LockBits(r, (ImageLockMode)0, PixelFormat.Format24bppRgb);
+ try
+ {
+ Assert.Equal(4, data.Height);
+ Assert.Equal(4, data.Width);
+ Assert.True(data.Stride >= 12);
+ Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat);
+ Assert.False(IntPtr.Zero.Equals(data.Scan0));
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_Double()
+ {
+ using (Bitmap bmp = new Bitmap(10, 10, PixelFormat.Format24bppRgb))
+ {
+ Rectangle r = new Rectangle(4, 4, 4, 4);
+ BitmapData data = bmp.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
+ try
+ {
+ Assert.Throws(() => bmp.LockBits(r, ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb));
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_Disposed()
+ {
+ Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb);
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ bmp.Dispose();
+ Assert.Throws(() => bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void UnlockBits_Null()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Assert.Throws(() => bmp.UnlockBits(null));
+ }
+ }
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_BitmapData_Null()
+ {
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ Assert.Throws(() => bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, null));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_32_32_BitmapData()
+ {
+ BitmapData data = new BitmapData();
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format32bppRgb, data.PixelFormat);
+ Assert.Equal(400, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_32_24_BitmapData()
+ {
+ BitmapData data = new BitmapData();
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format32bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat);
+ Assert.Equal(300, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_24_24_BitmapData()
+ {
+ BitmapData data = new BitmapData();
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format24bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb, data);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format24bppRgb, data.PixelFormat);
+ Assert.Equal(300, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBits_24_32_BitmapData()
+ {
+ BitmapData data = new BitmapData();
+ using (Bitmap bmp = new Bitmap(100, 100, PixelFormat.Format24bppRgb))
+ {
+ Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
+ bmp.LockBits(rect, ImageLockMode.ReadWrite, PixelFormat.Format32bppRgb, data);
+ Assert.Equal(100, data.Height);
+ Assert.Equal(PixelFormat.Format32bppRgb, data.PixelFormat);
+ Assert.Equal(400, data.Stride);
+ Assert.Equal(100, data.Width);
+ bmp.UnlockBits(data);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format1bppIndexed()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format1bppIndexed))
+ {
+ Color c = bmp.GetPixel(0, 0);
+ Assert.Equal(-16777216, c.ToArgb());
+ Assert.Throws(() => bmp.SetPixel(0, 0, c));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format4bppIndexed()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format4bppIndexed))
+ {
+ Color c = bmp.GetPixel(0, 0);
+ Assert.Equal(-16777216, c.ToArgb());
+ Assert.Throws(() => bmp.SetPixel(0, 0, c));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format8bppIndexed()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
+ {
+ Color c = bmp.GetPixel(0, 0);
+ Assert.Equal(-16777216, c.ToArgb());
+ Assert.Throws(() => bmp.SetPixel(0, 0, c));
+ }
+ }
+
+ private void FormatTest(PixelFormat format)
+ {
+ bool alpha = Image.IsAlphaPixelFormat(format);
+ int size = Image.GetPixelFormatSize(format) / 8 * 2;
+ using (Bitmap bmp = new Bitmap(2, 1, format))
+ {
+ Color a = Color.FromArgb(128, 64, 32, 16);
+ Color b = Color.FromArgb(192, 96, 48, 24);
+ bmp.SetPixel(0, 0, a);
+ bmp.SetPixel(1, 0, b);
+ Color c = bmp.GetPixel(0, 0);
+ Color d = bmp.GetPixel(1, 0);
+ if (size == 4)
+ {
+ Assert.Equal(255, c.A);
+ Assert.Equal(66, c.R);
+ if (format == PixelFormat.Format16bppRgb565)
+ {
+ Assert.Equal(32, c.G);
+ }
+ else
+ {
+ Assert.Equal(33, c.G);
+ }
+ Assert.Equal(16, c.B);
+
+ Assert.Equal(255, d.A);
+ Assert.Equal(99, d.R);
+ if (format == PixelFormat.Format16bppRgb565)
+ {
+ Assert.Equal(48, d.G);
+ }
+ else
+ {
+ Assert.Equal(49, d.G);
+ }
+ Assert.Equal(24, d.B);
+ }
+ else if (alpha)
+ {
+ if (format == PixelFormat.Format32bppPArgb)
+ {
+ Assert.Equal(a.A, c.A);
+ // note sure why the -1
+ Assert.Equal(a.R - 1, c.R);
+ Assert.Equal(a.G - 1, c.G);
+ Assert.Equal(a.B - 1, c.B);
+
+ Assert.Equal(b.A, d.A);
+ // note sure why the -1
+ Assert.Equal(b.R - 1, d.R);
+ Assert.Equal(b.G - 1, d.G);
+ Assert.Equal(b.B - 1, d.B);
+ }
+ else
+ {
+ Assert.Equal(a, c);
+ Assert.Equal(b, d);
+ }
+ }
+ else
+ {
+ Assert.Equal(Color.FromArgb(255, 64, 32, 16), c);
+ Assert.Equal(Color.FromArgb(255, 96, 48, 24), d);
+ }
+ BitmapData bd = bmp.LockBits(new Rectangle(0, 0, 2, 1), ImageLockMode.ReadOnly, format);
+ try
+ {
+ byte[] data = new byte[size];
+ Marshal.Copy(bd.Scan0, data, 0, size);
+ if (format == PixelFormat.Format32bppPArgb)
+ {
+ Assert.Equal(Math.Ceiling((float)c.B * c.A / 255), data[0]);
+ Assert.Equal(Math.Ceiling((float)c.G * c.A / 255), data[1]);
+ Assert.Equal(Math.Ceiling((float)c.R * c.A / 255), data[2]);
+ Assert.Equal(c.A, data[3]);
+ Assert.Equal(Math.Ceiling((float)d.B * d.A / 255), data[4]);
+ Assert.Equal(Math.Ceiling((float)d.G * d.A / 255), data[5]);
+ Assert.Equal(Math.Ceiling((float)d.R * d.A / 255), data[6]);
+ Assert.Equal(d.A, data[7]);
+ }
+ else if (size == 4)
+ {
+ int n = 0;
+ switch (format)
+ {
+ case PixelFormat.Format16bppRgb565:
+ Assert.Equal(2, data[n++]);
+ Assert.Equal(65, data[n++]);
+ Assert.Equal(131, data[n++]);
+ Assert.Equal(97, data[n++]);
+ break;
+ case PixelFormat.Format16bppArgb1555:
+ Assert.Equal(130, data[n++]);
+ Assert.Equal(160, data[n++]);
+ Assert.Equal(195, data[n++]);
+ Assert.Equal(176, data[n++]);
+ break;
+ case PixelFormat.Format16bppRgb555:
+ Assert.Equal(130, data[n++]);
+ Assert.Equal(32, data[n++]);
+ Assert.Equal(195, data[n++]);
+ Assert.Equal(48, data[n++]);
+ break;
+ }
+ }
+ else
+ {
+ int n = 0;
+ Assert.Equal(c.B, data[n++]);
+ Assert.Equal(c.G, data[n++]);
+ Assert.Equal(c.R, data[n++]);
+ if (size % 4 == 0)
+ Assert.Equal(c.A, data[n++]);
+ Assert.Equal(d.B, data[n++]);
+ Assert.Equal(d.G, data[n++]);
+ Assert.Equal(d.R, data[n++]);
+ if (size % 4 == 0)
+ Assert.Equal(d.A, data[n++]);
+ }
+ }
+ finally
+ {
+ bmp.UnlockBits(bd);
+ }
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format32bppArgb()
+ {
+ FormatTest(PixelFormat.Format32bppArgb);
+ }
+
+ [ActiveIssue(20884)]
+ public void Format32bppRgb()
+ {
+ FormatTest(PixelFormat.Format32bppRgb);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format24bppRgb()
+ {
+ FormatTest(PixelFormat.Format24bppRgb);
+ }
+
+ /* Get the output directory depending on the runtime and location*/
+ public static string getOutSubDir()
+ {
+ string sSub, sRslt;
+
+ if (Environment.GetEnvironmentVariable("MSNet") == null)
+ sSub = "mono/";
+ else
+ sSub = "MSNet/";
+
+ sRslt = Path.GetFullPath(sSub);
+
+ if (Directory.Exists(sRslt) == false)
+ sRslt = "Test/System.Drawing/" + sSub;
+
+ if (sRslt.Length > 0)
+ if (sRslt[sRslt.Length - 1] != '\\' && sRslt[sRslt.Length - 1] != '/')
+ sRslt += "/";
+
+ return sRslt;
+ }
+
+ // note: this test fails when saving (for the same reason) on Mono and MS.NET
+ //[ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void MakeTransparent()
+ {
+ string sInFile = Helpers.GetTestBitmapPath("maketransparent.bmp");
+ string sOutFile = getOutSubDir() + "transparent.bmp";
+
+ Bitmap bmp = new Bitmap(sInFile);
+
+ bmp.MakeTransparent();
+ bmp.Save(sOutFile);
+
+ Color color = bmp.GetPixel(1, 1);
+ Assert.Equal(Color.Black.R, color.R);
+ Assert.Equal(Color.Black.G, color.G);
+ Assert.Equal(Color.Black.B, color.B);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Clone()
+ {
+ string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp");
+ Rectangle rect = new Rectangle(0, 0, 50, 50);
+ Bitmap bmp = new Bitmap(sInFile);
+
+ Bitmap bmpNew = bmp.Clone(rect, PixelFormat.Format32bppArgb);
+ Color colororg0 = bmp.GetPixel(0, 0);
+ Color colororg50 = bmp.GetPixel(49, 49);
+ Color colornew0 = bmpNew.GetPixel(0, 0);
+ Color colornew50 = bmpNew.GetPixel(49, 49);
+
+ Assert.Equal(colororg0, colornew0);
+ Assert.Equal(colororg50, colornew50);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void CloneImage()
+ {
+ string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp");
+ Bitmap bmp = new Bitmap(sInFile);
+
+ Bitmap bmpNew = (Bitmap)bmp.Clone();
+
+ Assert.Equal(bmp.Width, bmpNew.Width);
+ Assert.Equal(bmp.Height, bmpNew.Height);
+ Assert.Equal(bmp.PixelFormat, bmpNew.PixelFormat);
+
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Frames()
+ {
+ string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp");
+ Bitmap bmp = new Bitmap(sInFile);
+ int cnt = bmp.GetFrameCount(FrameDimension.Page);
+ int active = bmp.SelectActiveFrame(FrameDimension.Page, 0);
+
+ Assert.Equal(1, cnt);
+ Assert.Equal(0, active);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void FileDoesNotExists()
+ {
+ Assert.Throws(() => new Bitmap("FileDoesNotExists.jpg"));
+ }
+
+ static string ByteArrayToString(byte[] arrInput)
+ {
+ int i;
+ StringBuilder sOutput = new StringBuilder(arrInput.Length);
+ for (i = 0; i < arrInput.Length - 1; i++)
+ {
+ sOutput.Append(arrInput[i].ToString("X2"));
+ }
+ return sOutput.ToString();
+ }
+
+
+ public string RotateBmp(Bitmap src, RotateFlipType rotate)
+ {
+ int width = 150, height = 150, index = 0;
+ byte[] pixels = new byte[width * height * 3];
+ Bitmap bmp_rotate;
+ byte[] hash;
+ Color clr;
+
+ bmp_rotate = src.Clone(new RectangleF(0, 0, width, height), PixelFormat.Format32bppArgb);
+ bmp_rotate.RotateFlip(rotate);
+
+ for (int y = 0; y < height; y++)
+ {
+ for (int x = 0; x < width; x++)
+ {
+ clr = bmp_rotate.GetPixel(x, y);
+ pixels[index++] = clr.R;
+ pixels[index++] = clr.G;
+ pixels[index++] = clr.B;
+ }
+ }
+
+ hash = MD5.Create().ComputeHash(pixels);
+ return ByteArrayToString(hash);
+ }
+ public string RotateIndexedBmp(Bitmap src, RotateFlipType type)
+ {
+ int pixels_per_byte;
+
+ switch (src.PixelFormat)
+ {
+ case PixelFormat.Format1bppIndexed:
+ pixels_per_byte = 8;
+ break;
+ case PixelFormat.Format4bppIndexed:
+ pixels_per_byte = 2;
+ break;
+ case PixelFormat.Format8bppIndexed:
+ pixels_per_byte = 1;
+ break;
+
+ default:
+ throw new Exception("Cannot pass a bitmap of format " + src.PixelFormat + " to RotateIndexedBmp");
+ }
+
+ Bitmap test = src.Clone() as Bitmap;
+
+ test.RotateFlip(type);
+
+ BitmapData data = null;
+ byte[] pixel_data;
+
+ try
+ {
+ data = test.LockBits(new Rectangle(0, 0, test.Width, test.Height), ImageLockMode.ReadOnly, test.PixelFormat);
+
+ int scan_size = (data.Width + pixels_per_byte - 1) / pixels_per_byte;
+ pixel_data = new byte[data.Height * scan_size];
+
+ for (int y = 0; y < data.Height; y++)
+ {
+ IntPtr src_ptr = (IntPtr)(y * data.Stride + data.Scan0.ToInt64());
+ int dest_offset = y * scan_size;
+ for (int x = 0; x < scan_size; x++)
+ pixel_data[dest_offset + x] = Marshal.ReadByte(src_ptr, x);
+ }
+ }
+ finally
+ {
+ if (test != null)
+ {
+ if (data != null)
+ try
+ { test.UnlockBits(data); }
+ catch { }
+
+ try
+ { test.Dispose(); }
+ catch { }
+ }
+ }
+
+ if (pixel_data == null)
+ return "--ERROR--";
+
+ byte[] hash = MD5.Create().ComputeHash(pixel_data);
+ return ByteArrayToString(hash);
+ }
+
+
+ /*
+ Rotate bitmap in diffent ways, and check the result
+ pixels using MD5
+ */
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Rotate()
+ {
+ string sInFile = Helpers.GetTestBitmapPath("almogaver24bits.bmp");
+ Bitmap bmp = new Bitmap(sInFile);
+
+ Assert.Equal("312958A3C67402E1299413794988A3", RotateBmp(bmp, RotateFlipType.Rotate90FlipNone));
+ Assert.Equal("BF70D8DA4F1545AEDD77D0296B47AE", RotateBmp(bmp, RotateFlipType.Rotate180FlipNone));
+ Assert.Equal("15AD2ADBDC7090C0EC744D0F7ACE2F", RotateBmp(bmp, RotateFlipType.Rotate270FlipNone));
+ Assert.Equal("2E10FEC1F4FD64ECC51D7CE68AEB18", RotateBmp(bmp, RotateFlipType.RotateNoneFlipX));
+ Assert.Equal("E63204779B566ED01162B90B49BD9E", RotateBmp(bmp, RotateFlipType.Rotate90FlipX));
+ Assert.Equal("B1ECB17B5093E13D04FF55CFCF7763", RotateBmp(bmp, RotateFlipType.Rotate180FlipX));
+ Assert.Equal("71A173882C16755D86F4BC26532374", RotateBmp(bmp, RotateFlipType.Rotate270FlipX));
+
+ }
+
+ /*
+ Rotate 1- and 4-bit bitmaps in different ways and check the
+ resulting pixels using MD5
+ */
+ [ConditionalFact(Helpers.RecentGdiplusIsAvailable)]
+ [PlatformSpecific(TestPlatforms.AnyUnix)]
+ public void Rotate1bit4bit()
+ {
+ string[] files = {
+ Helpers.GetTestBitmapPath ("1bit.png"),
+ Helpers.GetTestBitmapPath ("4bit.png")
+ };
+
+ StringBuilder md5s = new StringBuilder();
+
+ foreach (string file in files)
+ using (Bitmap bmp = new Bitmap(file))
+ foreach (RotateFlipType type in Enum.GetValues(typeof(RotateFlipType)))
+ md5s.Append(RotateIndexedBmp(bmp, type));
+
+ using (StreamWriter writer = new StreamWriter("/tmp/md5s.txt"))
+ writer.WriteLine(md5s);
+
+ Assert.Equal(
+ "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit RotateNoneFlipNone
+ "A4DAF507C92BDE10626BC7B34FEFE5" + // 1-bit Rotate180FlipXY
+ "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate90FlipNone
+ "C0975EAFD2FC1CC9CC7AF20B92FC9F" + // 1-bit Rotate270FlipXY
+ "64AE60858A02228F7B1B18C7812FB6" + // 1-bit Rotate180FlipNone
+ "64AE60858A02228F7B1B18C7812FB6" + // 1-bit RotateNoneFlipXY
+ "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate270FlipNone
+ "E96D3390938350F9DE2608C4364424" + // 1-bit Rotate90FlipXY
+ "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit RotateNoneFlipX
+ "23947CE822C1DDE6BEA69C01F8D0D9" + // 1-bit Rotate180FlipY
+ "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate90FlipX
+ "BE45F685BDEBD7079AA1B2CBA46723" + // 1-bit Rotate270FlipY
+ "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit Rotate180FlipX
+ "353E937CFF31B1BF6C3DD0A031ACB5" + // 1-bit RotateNoneFlipY
+ "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate270FlipX
+ "AEA18A770A845E25B6A8CE28DD6DCB" + // 1-bit Rotate90FlipY
+ "3CC874B571902366AACED5D619E87D" + // 4-bit RotateNoneFlipNone
+ "3CC874B571902366AACED5D619E87D" + // 4-bit Rotate180FlipXY
+ "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate90FlipNone
+ "8DE25C7E1BE4A3B535DB5D83198D83" + // 4-bit Rotate270FlipXY
+ "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit Rotate180FlipNone
+ "27CF5E9CE70BE9EBC47FB996721B95" + // 4-bit RotateNoneFlipXY
+ "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate270FlipNone
+ "A919CCB8F97CAD7DC1F01026D11A5D" + // 4-bit Rotate90FlipXY
+ "545876C99ACF833E69FBFFBF436034" + // 4-bit RotateNoneFlipX
+ "545876C99ACF833E69FBFFBF436034" + // 4-bit Rotate180FlipY
+ "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate90FlipX
+ "5DB56687757CDEFC52D89C77CA9223" + // 4-bit Rotate270FlipY
+ "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit Rotate180FlipX
+ "05A77EDDCDF20D5B0AC0169E95D7D7" + // 4-bit RotateNoneFlipY
+ "B6B6245796C836923ABAABDF368B29" + // 4-bit Rotate270FlipX
+ "B6B6245796C836923ABAABDF368B29", // 4-bit Rotate90FlipY
+ md5s.ToString());
+ }
+
+ private Bitmap CreateBitmap(int width, int height, PixelFormat fmt)
+ {
+ Bitmap bmp = new Bitmap(width, height, fmt);
+ using (Graphics gr = Graphics.FromImage(bmp))
+ {
+ Color c = Color.FromArgb(255, 100, 200, 250);
+ for (int x = 1; x < 80; x++)
+ {
+ bmp.SetPixel(x, 1, c);
+ bmp.SetPixel(x, 2, c);
+ bmp.SetPixel(x, 78, c);
+ bmp.SetPixel(x, 79, c);
+ }
+ for (int y = 3; y < 78; y++)
+ {
+ bmp.SetPixel(1, y, c);
+ bmp.SetPixel(2, y, c);
+ bmp.SetPixel(78, y, c);
+ bmp.SetPixel(79, y, c);
+ }
+ }
+ return bmp;
+ }
+
+ private byte[] HashPixels(Bitmap bmp)
+ {
+ int len = bmp.Width * bmp.Height * 4;
+ int index = 0;
+ byte[] pixels = new byte[len];
+
+ for (int y = 0; y < bmp.Height; y++)
+ {
+ for (int x = 0; x < bmp.Width; x++)
+ {
+ Color clr = bmp.GetPixel(x, y);
+ pixels[index++] = clr.R;
+ pixels[index++] = clr.G;
+ pixels[index++] = clr.B;
+ }
+ }
+ return MD5.Create().ComputeHash(pixels);
+ }
+
+ private byte[] HashLock(Bitmap bmp, int width, int height, PixelFormat fmt, ImageLockMode mode)
+ {
+ int len = bmp.Width * bmp.Height * 4;
+ byte[] pixels = new byte[len];
+ BitmapData bd = bmp.LockBits(new Rectangle(0, 0, width, height), mode, fmt);
+ try
+ {
+ int index = 0;
+ int bbps = Image.GetPixelFormatSize(fmt);
+ long pos = bd.Scan0.ToInt64();
+ byte[] btv = new byte[1];
+ for (int y = 0; y < bd.Height; y++)
+ {
+ for (int x = 0; x < bd.Width; x++)
+ {
+
+ /* Read the pixels*/
+ for (int bt = 0; bt < bbps / 8; bt++, index++)
+ {
+ long cur = pos;
+ cur += y * bd.Stride;
+ cur += x * bbps / 8;
+ cur += bt;
+ Marshal.Copy((IntPtr)cur, btv, 0, 1);
+ pixels[index] = btv[0];
+
+ /* Make change of all the colours = 250 to 10*/
+ if (btv[0] == 250)
+ {
+ btv[0] = 10;
+ Marshal.Copy(btv, 0, (IntPtr)cur, 1);
+ }
+ }
+ }
+ }
+
+ for (int i = index; i < len; i++)
+ pixels[index] = 0;
+ }
+ finally
+ {
+ bmp.UnlockBits(bd);
+ }
+ return MD5.Create().ComputeHash(pixels);
+ }
+
+ /*
+ Tests the LockBitmap functions. Makes a hash of the block of pixels that it returns
+ firsts, changes them, and then using GetPixel does another check of the changes.
+ The results match the .Net framework
+ */
+ private static byte[] DefaultBitmapHash = new byte[] { 0xD8, 0xD3, 0x68, 0x9C, 0x86, 0x7F, 0xB6, 0xA0, 0x76, 0xD6, 0x00, 0xEF, 0xFF, 0xE5, 0x8E, 0x1B };
+ private static byte[] FinalWholeBitmapHash = new byte[] { 0x5F, 0x52, 0x98, 0x37, 0xE3, 0x94, 0xE1, 0xA6, 0x06, 0x6C, 0x5B, 0xF1, 0xA9, 0xC2, 0xA9, 0x43 };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Whole()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
+ byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Whole()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x89, 0x6A, 0x6B, 0x35, 0x5C, 0x89, 0xD9, 0xE9, 0xF4, 0x51, 0xD5, 0x89, 0xED, 0x28, 0x68, 0x5C };
+ byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ActiveIssue(20884)]
+ public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Whole()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0xC0, 0x28, 0xB5, 0x2E, 0x86, 0x90, 0x6F, 0x37, 0x09, 0x5F, 0x49, 0xA4, 0x91, 0xDA, 0xEE, 0xB9 };
+ byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Whole()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0xA7, 0xB2, 0x50, 0x04, 0x11, 0x12, 0x64, 0x68, 0x6B, 0x7D, 0x2F, 0x6E, 0x69, 0x24, 0xCB, 0x14 };
+ byte[] actual = HashLock(bmp, bmp.Width, bmp.Height, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalWholeBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ private static byte[] FinalPartialBitmapHash = new byte[] { 0xED, 0xD8, 0xDC, 0x9B, 0x44, 0x00, 0x22, 0x9B, 0x07, 0x06, 0x4A, 0x21, 0x70, 0xA7, 0x31, 0x1D };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format32bppArgb_ReadWrite_Partial()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
+ byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppArgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format32bppPArgb_ReadWrite_Partial()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x5D, 0xFF, 0x02, 0x34, 0xEB, 0x7C, 0xF7, 0x42, 0xD4, 0xB7, 0x70, 0x49, 0xB4, 0x06, 0x79, 0xBC };
+ byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppPArgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ActiveIssue(20884)]
+ public void LockBitmap_Format32bppArgb_Format32bppRgb_ReadWrite_Partial()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x72, 0x33, 0x09, 0x67, 0x53, 0x65, 0x38, 0xF9, 0xE4, 0x58, 0xE1, 0x0A, 0xAA, 0x6A, 0xCC, 0xB8 };
+ byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format32bppRgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockBitmap_Format32bppArgb_Format24bppRgb_ReadWrite_Partial()
+ {
+ using (Bitmap bmp = CreateBitmap(100, 100, PixelFormat.Format32bppArgb))
+ {
+ Assert.Equal(DefaultBitmapHash, HashPixels(bmp));
+ byte[] expected = { 0x4D, 0x39, 0x21, 0x88, 0xC2, 0x17, 0x14, 0x5F, 0x89, 0x9E, 0x02, 0x75, 0xF3, 0x64, 0xD8, 0xF0 };
+ byte[] actual = HashLock(bmp, 50, 50, PixelFormat.Format24bppRgb, ImageLockMode.ReadWrite);
+ Assert.Equal(expected, actual);
+ Assert.Equal(FinalPartialBitmapHash, HashPixels(bmp));
+ }
+ }
+
+ /*
+ Tests the LockBitmap and UnlockBitmap functions, specifically the copying
+ of bitmap data in the directions indicated by the ImageLockMode.
+ */
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void LockUnlockBitmap()
+ {
+ BitmapData data;
+ int pixel_value;
+ Color pixel_colour;
+
+ Color red = Color.FromArgb(Color.Red.A, Color.Red.R, Color.Red.G, Color.Red.B);
+ Color blue = Color.FromArgb(Color.Blue.A, Color.Blue.R, Color.Blue.G, Color.Blue.B);
+
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppRgb))
+ {
+ bmp.SetPixel(0, 0, red);
+ pixel_colour = bmp.GetPixel(0, 0);
+ Assert.Equal(red, pixel_colour);
+
+ data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
+ try
+ {
+ pixel_value = Marshal.ReadByte(data.Scan0, 0);
+ pixel_value |= Marshal.ReadByte(data.Scan0, 1) << 8;
+ pixel_value |= Marshal.ReadByte(data.Scan0, 2) << 16;
+ pixel_value |= Marshal.ReadByte(data.Scan0, 3) << 24;
+
+ pixel_colour = Color.FromArgb(pixel_value);
+ // Disregard alpha information in the test
+ pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
+ Assert.Equal(red, pixel_colour);
+
+ // write blue but we're locked in read-only...
+ Marshal.WriteByte(data.Scan0, 0, blue.B);
+ Marshal.WriteByte(data.Scan0, 1, blue.G);
+ Marshal.WriteByte(data.Scan0, 2, blue.R);
+ Marshal.WriteByte(data.Scan0, 3, blue.A);
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ pixel_colour = bmp.GetPixel(0, 0);
+ // Disregard alpha information in the test
+ pixel_colour = Color.FromArgb(red.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
+ // ...so we still read red after unlocking
+ Assert.Equal(red, pixel_colour);
+ }
+
+ data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
+ try
+ {
+ // write blue
+ Marshal.WriteByte(data.Scan0, 0, blue.B);
+ Marshal.WriteByte(data.Scan0, 1, blue.G);
+ Marshal.WriteByte(data.Scan0, 2, blue.R);
+ Marshal.WriteByte(data.Scan0, 3, blue.A);
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ pixel_colour = bmp.GetPixel(0, 0);
+ // Disregard alpha information in the test
+ pixel_colour = Color.FromArgb(blue.A, pixel_colour.R, pixel_colour.G, pixel_colour.B);
+ // read blue
+ Assert.Equal(blue, pixel_colour);
+ }
+ }
+
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
+ {
+ bmp.SetPixel(0, 0, red);
+
+ data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb);
+ try
+ {
+ byte b = Marshal.ReadByte(data.Scan0, 0);
+ byte g = Marshal.ReadByte(data.Scan0, 1);
+ byte r = Marshal.ReadByte(data.Scan0, 2);
+ pixel_colour = Color.FromArgb(red.A, r, g, b);
+ Assert.Equal(red, pixel_colour);
+ // write blue but we're locked in read-only...
+ Marshal.WriteByte(data.Scan0, 0, blue.B);
+ Marshal.WriteByte(data.Scan0, 1, blue.G);
+ Marshal.WriteByte(data.Scan0, 2, blue.R);
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ // ...so we still read red after unlocking
+ Assert.Equal(red, bmp.GetPixel(0, 0));
+ }
+
+ data = bmp.LockBits(new Rectangle(0, 0, 1, 1), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
+ try
+ {
+ // write blue
+ Marshal.WriteByte(data.Scan0, 0, blue.B);
+ Marshal.WriteByte(data.Scan0, 1, blue.G);
+ Marshal.WriteByte(data.Scan0, 2, blue.R);
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ // read blue
+ Assert.Equal(blue, bmp.GetPixel(0, 0));
+ }
+ }
+ }
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DefaultFormat1()
+ {
+ using (Bitmap bmp = new Bitmap(20, 20))
+ {
+ Assert.Equal(ImageFormat.MemoryBmp, bmp.RawFormat);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void DefaultFormat2()
+ {
+ string filename = Path.GetTempFileName();
+ using (Bitmap bmp = new Bitmap(20, 20))
+ {
+ bmp.Save(filename);
+ }
+
+ using (Bitmap other = new Bitmap(filename))
+ {
+ Assert.Equal(ImageFormat.Png, other.RawFormat);
+ }
+ File.Delete(filename);
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BmpDataStride1()
+ {
+ Bitmap bmp = new Bitmap(184, 184, PixelFormat.Format1bppIndexed);
+ BitmapData data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format1bppIndexed);
+ try
+ {
+ Assert.Equal(24, data.Stride);
+ }
+ finally
+ {
+ bmp.UnlockBits(data);
+ bmp.Dispose();
+ }
+ }
+
+ private Stream Serialize(object o)
+ {
+ MemoryStream ms = new MemoryStream();
+ IFormatter formatter = new BinaryFormatter();
+ formatter.Serialize(ms, o);
+ ms.Position = 0;
+ return ms;
+ }
+
+ private object Deserialize(Stream s)
+ {
+ return new BinaryFormatter().Deserialize(s);
+ }
+
+ [ActiveIssue(20844)]
+ public void Serialize_Icon()
+ {
+ // this cause a problem with resgen, see http://bugzilla.ximian.com/show_bug.cgi?id=80565
+ string filename = Helpers.GetTestBitmapPath("16x16_one_entry_4bit.ico");
+ using (Bitmap icon = new Bitmap(filename))
+ {
+ using (Stream s = Serialize(icon))
+ {
+ using (Bitmap copy = (Bitmap)Deserialize(s))
+ {
+ Assert.Equal(icon.Height, copy.Height);
+ Assert.Equal(icon.Width, copy.Width);
+ Assert.Equal(icon.PixelFormat, copy.PixelFormat);
+ Assert.True(icon.RawFormat.Equals(ImageFormat.Icon));
+ Assert.True(copy.RawFormat.Equals(ImageFormat.Png));
+ }
+ }
+ }
+ }
+
+ static int[] palette1 = {
+ -16777216,
+ -1,
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format1bppIndexed_Palette()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format1bppIndexed))
+ {
+ ColorPalette pal = bmp.Palette;
+ Assert.Equal(2, pal.Entries.Length);
+ for (int i = 0; i < pal.Entries.Length; i++)
+ {
+ Assert.Equal(palette1[i], pal.Entries[i].ToArgb());
+ }
+ Assert.Equal(2, pal.Flags);
+ }
+ }
+
+ static int[] palette16 = {
+ -16777216,
+ -8388608,
+ -16744448,
+ -8355840,
+ -16777088,
+ -8388480,
+ -16744320,
+ -8355712,
+ -4144960,
+ -65536,
+ -16711936,
+ -256,
+ -16776961,
+ -65281,
+ -16711681,
+ -1,
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format4bppIndexed_Palette()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format4bppIndexed))
+ {
+ ColorPalette pal = bmp.Palette;
+ Assert.Equal(16, pal.Entries.Length);
+ for (int i = 0; i < pal.Entries.Length; i++)
+ {
+ Assert.Equal(palette16[i], pal.Entries[i].ToArgb());
+ }
+ Assert.Equal(0, pal.Flags);
+ }
+ }
+
+ static int[] palette256 = {
+ -16777216,
+ -8388608,
+ -16744448,
+ -8355840,
+ -16777088,
+ -8388480,
+ -16744320,
+ -8355712,
+ -4144960,
+ -65536,
+ -16711936,
+ -256,
+ -16776961,
+ -65281,
+ -16711681,
+ -1,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ -16777216,
+ -16777165,
+ -16777114,
+ -16777063,
+ -16777012,
+ -16776961,
+ -16764160,
+ -16764109,
+ -16764058,
+ -16764007,
+ -16763956,
+ -16763905,
+ -16751104,
+ -16751053,
+ -16751002,
+ -16750951,
+ -16750900,
+ -16750849,
+ -16738048,
+ -16737997,
+ -16737946,
+ -16737895,
+ -16737844,
+ -16737793,
+ -16724992,
+ -16724941,
+ -16724890,
+ -16724839,
+ -16724788,
+ -16724737,
+ -16711936,
+ -16711885,
+ -16711834,
+ -16711783,
+ -16711732,
+ -16711681,
+ -13434880,
+ -13434829,
+ -13434778,
+ -13434727,
+ -13434676,
+ -13434625,
+ -13421824,
+ -13421773,
+ -13421722,
+ -13421671,
+ -13421620,
+ -13421569,
+ -13408768,
+ -13408717,
+ -13408666,
+ -13408615,
+ -13408564,
+ -13408513,
+ -13395712,
+ -13395661,
+ -13395610,
+ -13395559,
+ -13395508,
+ -13395457,
+ -13382656,
+ -13382605,
+ -13382554,
+ -13382503,
+ -13382452,
+ -13382401,
+ -13369600,
+ -13369549,
+ -13369498,
+ -13369447,
+ -13369396,
+ -13369345,
+ -10092544,
+ -10092493,
+ -10092442,
+ -10092391,
+ -10092340,
+ -10092289,
+ -10079488,
+ -10079437,
+ -10079386,
+ -10079335,
+ -10079284,
+ -10079233,
+ -10066432,
+ -10066381,
+ -10066330,
+ -10066279,
+ -10066228,
+ -10066177,
+ -10053376,
+ -10053325,
+ -10053274,
+ -10053223,
+ -10053172,
+ -10053121,
+ -10040320,
+ -10040269,
+ -10040218,
+ -10040167,
+ -10040116,
+ -10040065,
+ -10027264,
+ -10027213,
+ -10027162,
+ -10027111,
+ -10027060,
+ -10027009,
+ -6750208,
+ -6750157,
+ -6750106,
+ -6750055,
+ -6750004,
+ -6749953,
+ -6737152,
+ -6737101,
+ -6737050,
+ -6736999,
+ -6736948,
+ -6736897,
+ -6724096,
+ -6724045,
+ -6723994,
+ -6723943,
+ -6723892,
+ -6723841,
+ -6711040,
+ -6710989,
+ -6710938,
+ -6710887,
+ -6710836,
+ -6710785,
+ -6697984,
+ -6697933,
+ -6697882,
+ -6697831,
+ -6697780,
+ -6697729,
+ -6684928,
+ -6684877,
+ -6684826,
+ -6684775,
+ -6684724,
+ -6684673,
+ -3407872,
+ -3407821,
+ -3407770,
+ -3407719,
+ -3407668,
+ -3407617,
+ -3394816,
+ -3394765,
+ -3394714,
+ -3394663,
+ -3394612,
+ -3394561,
+ -3381760,
+ -3381709,
+ -3381658,
+ -3381607,
+ -3381556,
+ -3381505,
+ -3368704,
+ -3368653,
+ -3368602,
+ -3368551,
+ -3368500,
+ -3368449,
+ -3355648,
+ -3355597,
+ -3355546,
+ -3355495,
+ -3355444,
+ -3355393,
+ -3342592,
+ -3342541,
+ -3342490,
+ -3342439,
+ -3342388,
+ -3342337,
+ -65536,
+ -65485,
+ -65434,
+ -65383,
+ -65332,
+ -65281,
+ -52480,
+ -52429,
+ -52378,
+ -52327,
+ -52276,
+ -52225,
+ -39424,
+ -39373,
+ -39322,
+ -39271,
+ -39220,
+ -39169,
+ -26368,
+ -26317,
+ -26266,
+ -26215,
+ -26164,
+ -26113,
+ -13312,
+ -13261,
+ -13210,
+ -13159,
+ -13108,
+ -13057,
+ -256,
+ -205,
+ -154,
+ -103,
+ -52,
+ -1,
+ };
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void Format8bppIndexed_Palette()
+ {
+ using (Bitmap bmp = new Bitmap(1, 1, PixelFormat.Format8bppIndexed))
+ {
+ ColorPalette pal = bmp.Palette;
+ Assert.Equal(256, pal.Entries.Length);
+ for (int i = 0; i < pal.Entries.Length; i++)
+ {
+ Assert.Equal(palette256[i], pal.Entries[i].ToArgb());
+ }
+ Assert.Equal(4, pal.Flags);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void XmlSerialization()
+ {
+ new XmlSerializer(typeof(Bitmap));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapImageCtor()
+ {
+ Assert.Throws(() => new Bitmap((Image)null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapImageSizeCtor()
+ {
+ Assert.Throws(() => new Bitmap((Image)null, Size.Empty));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapImageIntIntCtor()
+ {
+ Assert.Throws(() => new Bitmap((Image)null, Int32.MinValue, Int32.MaxValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapIntIntCtor()
+ {
+ Assert.Throws(() => new Bitmap(Int32.MinValue, Int32.MaxValue));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapIntIntGraphicCtor()
+ {
+ Assert.Throws(() => new Bitmap(1, 1, null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapIntIntPixelFormatCtor()
+ {
+ Assert.Throws(() => new Bitmap(Int32.MinValue, Int32.MaxValue, PixelFormat.Format1bppIndexed));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapStreamCtor()
+ {
+ AssertExtensions.Throws("stream", null, () => new Bitmap((Stream)null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapStreamBoolCtor()
+ {
+ AssertExtensions.Throws("stream", null, () => new Bitmap((Stream)null, true));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapStringCtor()
+ {
+ Assert.Throws(() => new Bitmap((string)null));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapStringBoolCtor()
+ {
+ Assert.Throws(() => new Bitmap((string)null, false));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapTypeStringCtor1()
+ {
+ Assert.Throws(() => new Bitmap((Type)null, "mono"));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void BitmapTypeStringCtor2()
+ {
+ Assert.Throws(() => new Bitmap(typeof(Bitmap), null));
+ }
+
+ private void SetResolution(float x, float y)
+ {
+ using (Bitmap bmp = new Bitmap(1, 1))
+ {
+ bmp.SetResolution(x, y);
+ }
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetResolution_Zero()
+ {
+ Assert.Throws(() => SetResolution(0.0f, 0.0f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetResolution_Negative_X()
+ {
+ Assert.Throws(() => SetResolution(-1.0f, 1.0f));
+ }
+
+ [ConditionalFact(Helpers.GdiplusIsAvailable)]
+ public void SetResolution_Negative_Y()
+ {
+ Assert.Throws