From 476fa9c6f56c4a8cd803600e085c3c9bdf62ff4c Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Sat, 17 Aug 2024 22:13:50 +0700 Subject: [PATCH 1/3] System.Numerics.Colors --- src/libraries/NetCoreAppLibrary.props | 1 + .../Directory.Build.props | 6 + .../System.Numerics.Colors/README.md | 7 + .../System.Numerics.Colors.sln | 449 ++++++++++++++++++ .../ref/System.Numerics.Colors.cs | 62 +++ .../ref/System.Numerics.Colors.csproj | 17 + .../src/Resources/Strings.resx | 123 +++++ .../src/System.Numerics.Colors.csproj | 29 ++ .../src/System/Numerics/Colors/Argb.T.cs | 139 ++++++ .../src/System/Numerics/Colors/Argb.cs | 57 +++ .../src/System/Numerics/Colors/Rgba.T.cs | 139 ++++++ .../src/System/Numerics/Colors/Rgba.cs | 57 +++ .../src/System/ThrowHelper.cs | 25 + .../tests/Argb.T.Tests.cs | 407 ++++++++++++++++ .../tests/Rgba.T.Tests.cs | 407 ++++++++++++++++ .../tests/System.Numerics.Colors.Tests.csproj | 19 + .../tests/TestHelpers.cs | 54 +++ .../shims/netstandard/src/netstandard.csproj | 1 + .../Common/scripts/crossgen2_comparison.py | 1 + 19 files changed, 2000 insertions(+) create mode 100644 src/libraries/System.Numerics.Colors/Directory.Build.props create mode 100644 src/libraries/System.Numerics.Colors/README.md create mode 100644 src/libraries/System.Numerics.Colors/System.Numerics.Colors.sln create mode 100644 src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.cs create mode 100644 src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.csproj create mode 100644 src/libraries/System.Numerics.Colors/src/Resources/Strings.resx create mode 100644 src/libraries/System.Numerics.Colors/src/System.Numerics.Colors.csproj create mode 100644 src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.T.cs create mode 100644 src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs create mode 100644 src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.T.cs create mode 100644 src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.cs create mode 100644 src/libraries/System.Numerics.Colors/src/System/ThrowHelper.cs create mode 100644 src/libraries/System.Numerics.Colors/tests/Argb.T.Tests.cs create mode 100644 src/libraries/System.Numerics.Colors/tests/Rgba.T.Tests.cs create mode 100644 src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj create mode 100644 src/libraries/System.Numerics.Colors/tests/TestHelpers.cs diff --git a/src/libraries/NetCoreAppLibrary.props b/src/libraries/NetCoreAppLibrary.props index a3f63978bf92da..b26e7245181e75 100644 --- a/src/libraries/NetCoreAppLibrary.props +++ b/src/libraries/NetCoreAppLibrary.props @@ -102,6 +102,7 @@ System.Net.WebProxy; System.Net.WebSockets; System.Net.WebSockets.Client; + System.Numerics.Colors; System.Numerics.Vectors; System.ObjectModel; System.Private.CoreLib; diff --git a/src/libraries/System.Numerics.Colors/Directory.Build.props b/src/libraries/System.Numerics.Colors/Directory.Build.props new file mode 100644 index 00000000000000..63f02a0f817ef2 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/Directory.Build.props @@ -0,0 +1,6 @@ + + + + Microsoft + + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Colors/README.md b/src/libraries/System.Numerics.Colors/README.md new file mode 100644 index 00000000000000..5658e529788abd --- /dev/null +++ b/src/libraries/System.Numerics.Colors/README.md @@ -0,0 +1,7 @@ +# System.Numerics.Colors + +Provides APIs for convertible colors that contains only raw color data. + +The intent is NOT to start building a general purpose image manipulation library. Libraries such as ImageSharp are the right answer for this. + +WinForms and System.Drawing will be able to leverage this for performance, which was the original driver for this request. diff --git a/src/libraries/System.Numerics.Colors/System.Numerics.Colors.sln b/src/libraries/System.Numerics.Colors/System.Numerics.Colors.sln new file mode 100644 index 00000000000000..8c6bbb61ee88be --- /dev/null +++ b/src/libraries/System.Numerics.Colors/System.Numerics.Colors.sln @@ -0,0 +1,449 @@ +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{CB567678-5F5D-4156-9D25-7FA4FA4ED506}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Numerics.Colors", "ref\System.Numerics.Colors.csproj", "{02334CFE-F006-448F-9A03-D42CC10CF296}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{2B15154E-1558-402E-B129-71D3F59D953F}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Numerics.Colors", "src\System.Numerics.Colors.csproj", "{62898AC3-0994-40EF-A5A9-CD2890879561}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tests", "tests", "{49E86110-64FA-45D2-BB3E-424BDBF5A0F6}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Numerics.Colors.Tests", "tests\System.Numerics.Colors.Tests.csproj", "{C02AB893-55AD-4F79-957D-442853D29F76}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilities", "..\Common\tests\TestUtilities\TestUtilities.csproj", "{E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{C5D919F7-E064-4205-9F58-6D681A9B66BA}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibraryImportGenerator", "..\System.Runtime.InteropServices\gen\LibraryImportGenerator\LibraryImportGenerator.csproj", "{9B89E064-DAC4-455A-AEF1-E8A523C07BB3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.Interop.SourceGeneration", "..\System.Runtime.InteropServices\gen\Microsoft.Interop.SourceGeneration\Microsoft.Interop.SourceGeneration.csproj", "{F8BBE961-0C53-490D-8416-E008E8A5CBDD}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{D07CAC0F-9F3A-4637-8EEE-237E02C7D184}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "gen", "gen", "{DAB8F24F-639C-4D6E-BE40-F62BE4276ABD}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILLink.CodeFixProvider", "..\..\tools\illink\src\ILLink.CodeFix\ILLink.CodeFixProvider.csproj", "{DF12A332-4C68-415C-ADAB-8FA81A0812CE}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILLink.RoslynAnalyzer", "..\..\tools\illink\src\ILLink.RoslynAnalyzer\ILLink.RoslynAnalyzer.csproj", "{E9F84761-6C5D-4D07-B861-ED3D04666543}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "ref", "ref", "{596E77AC-5198-48D7-81B8-4C9CE46636D4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Linker", "..\..\tools\illink\src\linker\ref\Mono.Linker.csproj", "{EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{64A1C403-FBB6-492D-BF52-1826B0F392A2}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILLink.Tasks", "..\..\tools\illink\src\ILLink.Tasks\ILLink.Tasks.csproj", "{D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Linker", "..\..\tools\illink\src\linker\Mono.Linker.csproj", "{8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Runtime", "..\System.Runtime\ref\System.Runtime.csproj", "{558174E5-8096-402E-ACA2-E068B8E65BCA}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Checked|Any CPU = Checked|Any CPU + Checked|arm = Checked|arm + Checked|arm64 = Checked|arm64 + Checked|x64 = Checked|x64 + Checked|x86 = Checked|x86 + Debug|Any CPU = Debug|Any CPU + Debug|arm = Debug|arm + Debug|arm64 = Debug|arm64 + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|arm = Release|arm + Release|arm64 = Release|arm64 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|Any CPU.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|arm.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|arm.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|arm64.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|arm64.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|x64.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|x64.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|x86.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Checked|x86.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|Any CPU.Build.0 = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|arm.ActiveCfg = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|arm.Build.0 = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|arm64.ActiveCfg = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|arm64.Build.0 = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|x64.ActiveCfg = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|x64.Build.0 = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|x86.ActiveCfg = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Debug|x86.Build.0 = Debug|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|Any CPU.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|arm.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|arm.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|arm64.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|arm64.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|x64.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|x64.Build.0 = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|x86.ActiveCfg = Release|Any CPU + {02334CFE-F006-448F-9A03-D42CC10CF296}.Release|x86.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|Any CPU.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|arm.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|arm.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|arm64.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|arm64.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|x64.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|x64.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|x86.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Checked|x86.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|Any CPU.Build.0 = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|arm.ActiveCfg = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|arm.Build.0 = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|arm64.ActiveCfg = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|arm64.Build.0 = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|x64.ActiveCfg = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|x64.Build.0 = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|x86.ActiveCfg = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Debug|x86.Build.0 = Debug|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|Any CPU.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|Any CPU.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|arm.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|arm.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|arm64.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|arm64.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|x64.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|x64.Build.0 = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|x86.ActiveCfg = Release|Any CPU + {62898AC3-0994-40EF-A5A9-CD2890879561}.Release|x86.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|Any CPU.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|arm.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|arm.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|arm64.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|arm64.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|x64.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|x64.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|x86.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Checked|x86.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|arm.ActiveCfg = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|arm.Build.0 = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|arm64.ActiveCfg = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|arm64.Build.0 = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|x64.ActiveCfg = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|x64.Build.0 = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|x86.ActiveCfg = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Debug|x86.Build.0 = Debug|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|Any CPU.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|arm.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|arm.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|arm64.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|arm64.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|x64.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|x64.Build.0 = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|x86.ActiveCfg = Release|Any CPU + {C02AB893-55AD-4F79-957D-442853D29F76}.Release|x86.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|Any CPU.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|arm.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|arm.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|arm64.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|arm64.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|x64.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|x64.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|x86.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Checked|x86.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|arm.ActiveCfg = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|arm.Build.0 = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|arm64.ActiveCfg = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|arm64.Build.0 = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|x64.ActiveCfg = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|x64.Build.0 = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|x86.ActiveCfg = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Debug|x86.Build.0 = Debug|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|Any CPU.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|arm.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|arm.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|arm64.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|arm64.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|x64.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|x64.Build.0 = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|x86.ActiveCfg = Release|Any CPU + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C}.Release|x86.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|Any CPU.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|arm.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|arm.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|arm64.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|arm64.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|x64.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|x64.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|x86.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Checked|x86.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|arm.ActiveCfg = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|arm.Build.0 = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|arm64.ActiveCfg = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|arm64.Build.0 = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|x64.ActiveCfg = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|x64.Build.0 = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|x86.ActiveCfg = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Debug|x86.Build.0 = Debug|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|Any CPU.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|arm.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|arm.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|arm64.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|arm64.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|x64.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|x64.Build.0 = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|x86.ActiveCfg = Release|Any CPU + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3}.Release|x86.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|Any CPU.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|arm.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|arm.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|arm64.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|arm64.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|x64.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|x64.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|x86.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Checked|x86.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|arm.ActiveCfg = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|arm.Build.0 = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|arm64.ActiveCfg = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|arm64.Build.0 = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|x64.ActiveCfg = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|x64.Build.0 = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|x86.ActiveCfg = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Debug|x86.Build.0 = Debug|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|Any CPU.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|arm.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|arm.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|arm64.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|arm64.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|x64.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|x64.Build.0 = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|x86.ActiveCfg = Release|Any CPU + {F8BBE961-0C53-490D-8416-E008E8A5CBDD}.Release|x86.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|Any CPU.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|arm.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|arm.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|arm64.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|arm64.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|x64.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|x64.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|x86.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Checked|x86.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|arm.ActiveCfg = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|arm.Build.0 = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|arm64.ActiveCfg = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|arm64.Build.0 = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|x64.ActiveCfg = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|x64.Build.0 = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|x86.ActiveCfg = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Debug|x86.Build.0 = Debug|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|Any CPU.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|arm.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|arm.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|arm64.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|arm64.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|x64.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|x64.Build.0 = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|x86.ActiveCfg = Release|Any CPU + {DF12A332-4C68-415C-ADAB-8FA81A0812CE}.Release|x86.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|Any CPU.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|arm.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|arm.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|arm64.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|arm64.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|x64.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|x64.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|x86.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Checked|x86.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|arm.ActiveCfg = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|arm.Build.0 = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|arm64.ActiveCfg = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|arm64.Build.0 = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|x64.ActiveCfg = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|x64.Build.0 = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|x86.ActiveCfg = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Debug|x86.Build.0 = Debug|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|Any CPU.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|arm.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|arm.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|arm64.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|arm64.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|x64.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|x64.Build.0 = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|x86.ActiveCfg = Release|Any CPU + {E9F84761-6C5D-4D07-B861-ED3D04666543}.Release|x86.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|Any CPU.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|arm.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|arm.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|arm64.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|arm64.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|x64.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|x64.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|x86.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Checked|x86.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|arm.ActiveCfg = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|arm.Build.0 = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|arm64.ActiveCfg = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|arm64.Build.0 = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|x64.ActiveCfg = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|x64.Build.0 = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|x86.ActiveCfg = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Debug|x86.Build.0 = Debug|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|Any CPU.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|arm.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|arm.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|arm64.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|arm64.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|x64.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|x64.Build.0 = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|x86.ActiveCfg = Release|Any CPU + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE}.Release|x86.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|Any CPU.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|arm.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|arm.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|arm64.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|arm64.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|x64.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|x64.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|x86.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Checked|x86.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|arm.ActiveCfg = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|arm.Build.0 = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|arm64.ActiveCfg = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|arm64.Build.0 = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|x64.ActiveCfg = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|x64.Build.0 = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|x86.ActiveCfg = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Debug|x86.Build.0 = Debug|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|Any CPU.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|arm.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|arm.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|arm64.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|arm64.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|x64.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|x64.Build.0 = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|x86.ActiveCfg = Release|Any CPU + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35}.Release|x86.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|Any CPU.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|Any CPU.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|arm.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|arm.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|arm64.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|arm64.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|x64.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|x64.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|x86.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Checked|x86.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|arm.ActiveCfg = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|arm.Build.0 = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|arm64.ActiveCfg = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|arm64.Build.0 = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|x64.ActiveCfg = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|x64.Build.0 = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|x86.ActiveCfg = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Debug|x86.Build.0 = Debug|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|Any CPU.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|arm.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|arm.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|arm64.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|arm64.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|x64.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|x64.Build.0 = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|x86.ActiveCfg = Release|Any CPU + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E}.Release|x86.Build.0 = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|Any CPU.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|Any CPU.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|arm.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|arm.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|arm64.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|arm64.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|x64.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|x64.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|x86.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Checked|x86.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|arm.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|arm.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|arm64.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|arm64.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|x64.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|x64.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|x86.ActiveCfg = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Debug|x86.Build.0 = Debug|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|Any CPU.Build.0 = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|arm.ActiveCfg = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|arm.Build.0 = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|arm64.ActiveCfg = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|arm64.Build.0 = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|x64.ActiveCfg = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|x64.Build.0 = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|x86.ActiveCfg = Release|Any CPU + {558174E5-8096-402E-ACA2-E068B8E65BCA}.Release|x86.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {02334CFE-F006-448F-9A03-D42CC10CF296} = {CB567678-5F5D-4156-9D25-7FA4FA4ED506} + {62898AC3-0994-40EF-A5A9-CD2890879561} = {2B15154E-1558-402E-B129-71D3F59D953F} + {C02AB893-55AD-4F79-957D-442853D29F76} = {49E86110-64FA-45D2-BB3E-424BDBF5A0F6} + {E4A1E771-FD5B-4D0B-AA5B-DA5E3BEAB45C} = {49E86110-64FA-45D2-BB3E-424BDBF5A0F6} + {9B89E064-DAC4-455A-AEF1-E8A523C07BB3} = {C5D919F7-E064-4205-9F58-6D681A9B66BA} + {F8BBE961-0C53-490D-8416-E008E8A5CBDD} = {C5D919F7-E064-4205-9F58-6D681A9B66BA} + {DAB8F24F-639C-4D6E-BE40-F62BE4276ABD} = {D07CAC0F-9F3A-4637-8EEE-237E02C7D184} + {DF12A332-4C68-415C-ADAB-8FA81A0812CE} = {DAB8F24F-639C-4D6E-BE40-F62BE4276ABD} + {E9F84761-6C5D-4D07-B861-ED3D04666543} = {DAB8F24F-639C-4D6E-BE40-F62BE4276ABD} + {596E77AC-5198-48D7-81B8-4C9CE46636D4} = {D07CAC0F-9F3A-4637-8EEE-237E02C7D184} + {EEE2BD1F-8FA5-4CA3-8497-F8BA3CEF68DE} = {596E77AC-5198-48D7-81B8-4C9CE46636D4} + {64A1C403-FBB6-492D-BF52-1826B0F392A2} = {D07CAC0F-9F3A-4637-8EEE-237E02C7D184} + {D9FA1966-B7DD-43A1-9B3A-6BFC69A8AB35} = {64A1C403-FBB6-492D-BF52-1826B0F392A2} + {8BD4465D-90EF-4EDD-B7F8-9DF3C3ACF90E} = {64A1C403-FBB6-492D-BF52-1826B0F392A2} + {558174E5-8096-402E-ACA2-E068B8E65BCA} = {CB567678-5F5D-4156-9D25-7FA4FA4ED506} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {560EE5AC-448C-4F52-915C-D2C99FF706ED} + EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + ..\..\tools\illink\src\ILLink.Shared\ILLink.Shared.projitems*{8bd4465d-90ef-4edd-b7f8-9df3c3acf90e}*SharedItemsImports = 5 + ..\..\tools\illink\src\ILLink.Shared\ILLink.Shared.projitems*{e9f84761-6c5d-4d07-b861-ed3d04666543}*SharedItemsImports = 5 + EndGlobalSection +EndGlobal diff --git a/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.cs b/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.cs new file mode 100644 index 00000000000000..eac47834439d19 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.cs @@ -0,0 +1,62 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// ------------------------------------------------------------------------------ +// Changes to this file must follow the https://aka.ms/api-review process. +// ------------------------------------------------------------------------------ + +namespace System.Numerics.Colors +{ +#pragma warning disable CS3001 // Argument type is not CLS-compliant +#pragma warning disable CS3002 // Return type is not CLS-compliant + + public static class Argb + { + public static System.Numerics.Colors.Argb CreateBigEndian(uint color) { throw null; } + public static System.Numerics.Colors.Argb CreateLittleEndian(uint color) { throw null; } + public static uint ToUInt32BigEndian(this System.Numerics.Colors.Argb color) { throw null; } + public static uint ToUInt32LittleEndian(this System.Numerics.Colors.Argb color) { throw null; } + } + + public readonly struct Argb : System.IEquatable>//, System.IFormattable, System.ISpanFormattable + where T : struct + { + private readonly T _dummyT; + public T A { get { throw null; } init { throw null; } } + public T R { get { throw null; } init { throw null; } } + public T G { get { throw null; } init { throw null; } } + public T B { get { throw null; } init { throw null; } } + public Argb(T a, T r, T g, T b) { throw null; } + public Argb(System.ReadOnlySpan values) { throw null; } + public void CopyTo(System.Span destination) { throw null; } + public bool Equals(System.Numerics.Colors.Argb other) { throw null; } + //public string ToString(string format, IFormatProvider formatProvider) { throw null; } + public System.Numerics.Colors.Rgba ToRgba() { throw null; } + } + + public static class Rgba + { + public static System.Numerics.Colors.Rgba CreateBigEndian(uint color) { throw null; } + public static System.Numerics.Colors.Rgba CreateLittleEndian(uint color) { throw null; } + public static uint ToUInt32BigEndian(this System.Numerics.Colors.Rgba color) { throw null; } + public static uint ToUInt32LittleEndian(this System.Numerics.Colors.Rgba color) { throw null; } + } + + public readonly struct Rgba : System.IEquatable>//, IFormattable, ISpanFormattable + where T : struct + { + private readonly T _dummyT; + public T R { get { throw null; } init { throw null; } } + public T G { get { throw null; } init { throw null; } } + public T B { get { throw null; } init { throw null; } } + public T A { get { throw null; } init { throw null; } } + public Rgba(T r, T g, T b, T a) { throw null; } + public Rgba(System.ReadOnlySpan values) { throw null; } + public void CopyTo(System.Span destination) { throw null; } + public bool Equals(System.Numerics.Colors.Rgba other) { throw null; } + //public string ToString(string format, IFormatProvider formatProvider) { throw null; } + public System.Numerics.Colors.Argb ToArgb() { throw null; } + } + +#pragma warning restore CS3001 // Argument type is not CLS-compliant +#pragma warning restore CS3002 // Return type is not CLS-compliant +} diff --git a/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.csproj b/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.csproj new file mode 100644 index 00000000000000..942d1d1409257b --- /dev/null +++ b/src/libraries/System.Numerics.Colors/ref/System.Numerics.Colors.csproj @@ -0,0 +1,17 @@ + + + + $(NetCoreAppCurrent) + enable + true + + + + + + + + + + + diff --git a/src/libraries/System.Numerics.Colors/src/Resources/Strings.resx b/src/libraries/System.Numerics.Colors/src/Resources/Strings.resx new file mode 100644 index 00000000000000..97e4a1e228e34e --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/Resources/Strings.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Span must have exactly {0} elements for Color components. + + \ No newline at end of file diff --git a/src/libraries/System.Numerics.Colors/src/System.Numerics.Colors.csproj b/src/libraries/System.Numerics.Colors/src/System.Numerics.Colors.csproj new file mode 100644 index 00000000000000..4ad5e9b96d647d --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System.Numerics.Colors.csproj @@ -0,0 +1,29 @@ + + + + $(NetCoreAppCurrent) + enable + true + + + + + + + + + + + + + ResXFileCodeGenerator + + + + + + + + + + diff --git a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.T.cs b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.T.cs new file mode 100644 index 00000000000000..84120e37052c07 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.T.cs @@ -0,0 +1,139 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Numerics.Colors +{ + /// + /// Represents a color in the ARGB (Alpha, Red, Green, Blue) color space. + /// + /// The type of the color components. + [StructLayout(LayoutKind.Sequential)] + [DebuggerDisplay("ARGB({A}, {R}, {G}, {B})")] + public readonly struct Argb : IEquatable>//, IFormattable, ISpanFormattable + where T : struct + { + // big-endian order + + /// + /// The alpha component of the color. + /// + public T A { get; init; } + + /// + /// The red component of the color. + /// + public T R { get; init; } + + /// + /// The green component of the color. + /// + public T G { get; init; } + + /// + /// The blue component of the color. + /// + public T B { get; init; } + + /// + /// Initializes a new instance of the color struct with the specified alpha, red, green, + /// and blue components. + /// + /// The alpha component. + /// The red component. + /// The green component. + /// The blue component. + public Argb(T a, T r, T g, T b) + { + A = a; + R = r; + G = g; + B = b; + } + + /// + /// Initializes a new instance of the color struct with the color components from + /// in the order alpha, red, green, blue. + /// + /// + /// The containing the color components in the order alpha, red, green, blue. + /// + public Argb(ReadOnlySpan values) + { + ThrowHelper.ThrowIfSpanDoesntHaveFourElementsForColor(values); + + this = Unsafe.As>(ref MemoryMarshal.GetReference(values)); + } + + /// + /// Copies this color components to the in the order + /// alpha, red, green, blue. + /// + /// + /// The to which the color components will be copied in the order alpha, red, green, blue. + /// + public void CopyTo(Span destination) + { + ThrowHelper.ThrowIfSpanDoesntHaveFourElementsForColor((ReadOnlySpan)destination); + + Unsafe.As>(ref MemoryMarshal.GetReference(destination)) = this; + } + + /// + /// Determines whether this color is equal to the color. + /// + /// + /// The other color to compare with this color. + /// + /// + /// if this color is equal to the + /// color; otherwise, . + /// + public bool Equals(Argb other) + { + EqualityComparer comparer = EqualityComparer.Default; + return comparer.Equals(A, other.A) && + comparer.Equals(R, other.R) && + comparer.Equals(G, other.G) && + comparer.Equals(B, other.B); + } + + /// + /// Determines whether this color is equal to the specified + /// object. + /// + /// The object to compare with this color. + /// + /// if the specified object is equal to this + /// color; otherwise, . + /// + public override bool Equals(object? obj) => obj is Argb otherColor && Equals(otherColor); + + /// + /// Default hash function for this color. + /// + /// A hash code for this color. + public override int GetHashCode() => HashCode.Combine(A, R, G, B); + + /// + /// Returns a string representation of this color. + /// + /// + /// A string in the format "[ARGB Color: A, R, G, B]", where A, R, G, and B are the alpha, red, green, and blue + /// component values of the color, respectively. + /// + public override string ToString() => $"[ARGB Color: {A}, {R}, {G}, {B}]"; + + /// + /// Converts this color to an color. + /// + /// + /// An new instance of the color that represents this color. + /// + public Rgba ToRgba() => new Rgba(R, G, B, A); + } +} diff --git a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs new file mode 100644 index 00000000000000..db9e8721783da7 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Binary; +using System.Runtime.CompilerServices; + +namespace System.Numerics.Colors +{ +#pragma warning disable CS3001 // Argument type is not CLS-compliant +#pragma warning disable CS3002 // Return type is not CLS-compliant + + /// + /// Static methods for color. + /// + public static class Argb + { + /// + /// Creates an color from a big-endian representing an ARGB color. + /// + /// A big-endian representing an ARGB color. + /// An new instance of the color. + public static Argb CreateBigEndian(uint color) => Unsafe.As>(ref color); + + /// + /// Creates an color from a little-endian representing an ARGB + /// color. + /// + /// A little-endian representing an ARGB color. + /// An new instance of the color. + public static Argb CreateLittleEndian(uint color) + { + color = BinaryPrimitives.ReverseEndianness(color); + return Unsafe.As>(ref color); + } + + /// + /// Converts the specified color to a big-endian representing an + /// ARGB color. + /// + /// The color to convert. + /// A big-endian representing an ARGB color. + public static uint ToUInt32BigEndian(this Argb color) + => Unsafe.As, uint>(ref color); + + /// + /// Converts the specified color to a little-endian representing + /// an ARGB color. + /// + /// The color to convert. + /// A little-endian representing an ARGB color. + public static uint ToUInt32LittleEndian(this Argb color) + => BinaryPrimitives.ReverseEndianness(Unsafe.As, uint>(ref color)); + } + +#pragma warning restore CS3001 // Argument type is not CLS-compliant +#pragma warning restore CS3002 // Return type is not CLS-compliant +} diff --git a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.T.cs b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.T.cs new file mode 100644 index 00000000000000..86243c7828df80 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.T.cs @@ -0,0 +1,139 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Diagnostics; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +namespace System.Numerics.Colors +{ + /// + /// Represents a color in the RGBA (Red, Green, Blue, Alpha) color space. + /// + /// The type of the color components. + [StructLayout(LayoutKind.Sequential)] + [DebuggerDisplay("RGBA({R}, {G}, {B}, {A})")] + public readonly struct Rgba : IEquatable>//, IFormattable, ISpanFormattable + where T : struct + { + // big-endian order + + /// + /// The red component of the color. + /// + public T R { get; init; } + + /// + /// The green component of the color. + /// + public T G { get; init; } + + /// + /// The blue component of the color. + /// + public T B { get; init; } + + /// + /// The alpha component of the color. + /// + public T A { get; init; } + + /// + /// Initializes a new instance of the color struct with the specified red, green, blue + /// and alpha components. + /// + /// The red component. + /// The green component. + /// The blue component. + /// The alpha component. + public Rgba(T r, T g, T b, T a) + { + R = r; + G = g; + B = b; + A = a; + } + + /// + /// Initializes a new instance of the color struct with the color components from + /// in the order red, green, blue, alpha. + /// + /// + /// The containing the color components in the order red, green, blue, alpha. + /// + public Rgba(ReadOnlySpan values) + { + ThrowHelper.ThrowIfSpanDoesntHaveFourElementsForColor(values); + + this = Unsafe.As>(ref MemoryMarshal.GetReference(values)); + } + + /// + /// Copies this color components to the in the order + /// red, green, blue, alpha. + /// + /// + /// The to which the color components will be copied in the order red, green, blue, alpha. + /// + public void CopyTo(Span destination) + { + ThrowHelper.ThrowIfSpanDoesntHaveFourElementsForColor((ReadOnlySpan)destination); + + Unsafe.As>(ref MemoryMarshal.GetReference(destination)) = this; + } + + /// + /// Determines whether this color is equal to the color. + /// + /// + /// The other color to compare with this color. + /// + /// + /// if this color is equal to the + /// color; otherwise, . + /// + public bool Equals(Rgba other) + { + EqualityComparer comparer = EqualityComparer.Default; + return comparer.Equals(R, other.R) && + comparer.Equals(G, other.G) && + comparer.Equals(B, other.B) && + comparer.Equals(A, other.A); + } + + /// + /// Determines whether this color is equal to the specified + /// object. + /// + /// The object to compare with this color. + /// + /// if the specified object is equal to this + /// color; otherwise, . + /// + public override bool Equals(object? obj) => obj is Rgba other && Equals(other); + + /// + /// Default hash function for this color. + /// + /// A hash code for this color. + public override int GetHashCode() => HashCode.Combine(R, G, B, A); + + /// + /// Returns a string representation of this color. + /// + /// + /// A string in the format "[RGBA Color: R, G, B, A]", where R, G, B, and A are the red, green, blue, and alpha + /// component values of the color, respectively. + /// + public override string ToString() => $"[RGBA Color: {R}, {G}, {B}, {A}]"; + + /// + /// Converts this color to an color. + /// + /// + /// An new instance of the color that represents this color. + /// + public Argb ToArgb() => new Argb(A, R, G, B); + } +} diff --git a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.cs b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.cs new file mode 100644 index 00000000000000..fb498fc9ce4816 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Rgba.cs @@ -0,0 +1,57 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Buffers.Binary; +using System.Runtime.CompilerServices; + +namespace System.Numerics.Colors +{ +#pragma warning disable CS3001 // Argument type is not CLS-compliant +#pragma warning disable CS3002 // Return type is not CLS-compliant + + /// + /// Static methods for color. + /// + public static class Rgba + { + /// + /// Creates an color from a big-endian representing an RGBA color. + /// + /// A big-endian representing an RGBA color. + /// An new instance of the color. + public static Rgba CreateBigEndian(uint color) => Unsafe.As>(ref color); + + /// + /// Creates an color from a little-endian representing an RGBA + /// color. + /// + /// A little-endian representing an RGBA color. + /// An new instance of the color. + public static Rgba CreateLittleEndian(uint color) + { + color = BinaryPrimitives.ReverseEndianness(color); + return Unsafe.As>(ref color); + } + + /// + /// Converts the specified color to a big-endian representing an + /// RGBA color. + /// + /// The color to convert. + /// A big-endian representing an RGBA color. + public static uint ToUInt32BigEndian(this Rgba color) + => Unsafe.As, uint>(ref color); + + /// + /// Converts the specified color to a little-endian representing + /// an RGBA color. + /// + /// The color to convert. + /// A little-endian representing an RGBA color. + public static uint ToUInt32LittleEndian(this Rgba color) + => BinaryPrimitives.ReverseEndianness(Unsafe.As, uint>(ref color)); + } + +#pragma warning restore CS3001 // Argument type is not CLS-compliant +#pragma warning restore CS3002 // Return type is not CLS-compliant +} diff --git a/src/libraries/System.Numerics.Colors/src/System/ThrowHelper.cs b/src/libraries/System.Numerics.Colors/src/System/ThrowHelper.cs new file mode 100644 index 00000000000000..120de03cd84ecc --- /dev/null +++ b/src/libraries/System.Numerics.Colors/src/System/ThrowHelper.cs @@ -0,0 +1,25 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Diagnostics; +using System.Runtime.CompilerServices; + +namespace System +{ + internal static class ThrowHelper + { + [StackTraceHidden] + internal static void ThrowIfSpanDoesntHaveFourElementsForColor(ReadOnlySpan span, + [CallerArgumentExpression(nameof(span))] string? paramName = null) + { + if (span.Length != 4) + ThrowSpanDoesntHaveFourElementsForColor(paramName); + } + + [StackTraceHidden] + internal static void ThrowSpanDoesntHaveFourElementsForColor(string? paramName = null) + { + throw new ArgumentException(SR.Format(SR.Arg_SpanMustHaveElementsForColor, "4"), paramName); + } + } +} diff --git a/src/libraries/System.Numerics.Colors/tests/Argb.T.Tests.cs b/src/libraries/System.Numerics.Colors/tests/Argb.T.Tests.cs new file mode 100644 index 00000000000000..3c35bf00a13a74 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/Argb.T.Tests.cs @@ -0,0 +1,407 @@ +using Xunit; + +namespace System.Numerics.Colors.Tests +{ + public class ArgbTTests + { + [Fact] + public void ArgbT_Default() + { + { + // Act + Argb color = default; + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Argb color = new(default, default, default, default); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Argb color = new([default, default, default, default]); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act & Assert + Assert.Throws(() => new Argb(null)); + Assert.Throws(() => new Argb(default)); + Assert.Throws(() => new Argb([default, default, default])); + Assert.Throws(() => new Argb([default, default, default, default, default])); + } + + { + // Act + Argb color = default; + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Argb color = new(default, default, default, default); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Argb color = new([default, default, default, default]); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act & Assert + Assert.Throws(() => new Argb(null)); + Assert.Throws(() => new Argb(default)); + Assert.Throws(() => new Argb([default, default, default])); + Assert.Throws(() => new Argb([default, default, default, default, default])); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void ArgbT_CtorArgb(byte alpha, byte red, byte green, byte blue) + { + { + // Act + var color = new Argb(alpha, red, green, blue); + + // Assert + Assert.Equal(alpha, color.A); + Assert.Equal(red, color.R); + Assert.Equal(green, color.G); + Assert.Equal(blue, color.B); + } + + { + // Arrange + var alphaF = alpha.FloatC(); var redF = red.FloatC(); var greenF = green.FloatC(); + var blueF = blue.FloatC(); + + // Act + var color = new Argb(alphaF, redF, greenF, blueF); + + // Assert + Assert.Equal(alphaF, color.A); + Assert.Equal(redF, color.R); + Assert.Equal(greenF, color.G); + Assert.Equal(blueF, color.B); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void ArgbT_CtorSpan(byte alpha, byte red, byte green, byte blue) + { + { + // Arrange + byte[] values = [default, alpha, red, green, blue, default]; + + // Act + var color = new Argb(values.AsSpan(1, 4)); + + // Assert + Assert.Equal(alpha, color.A); + Assert.Equal(red, color.R); + Assert.Equal(green, color.G); + Assert.Equal(blue, color.B); + + // Act & Assert + Assert.Throws(() => new Argb([red, green, blue])); + Assert.Throws(() => new Argb([alpha, red, green, blue, alpha])); + } + + { + // Arrange + var alphaF = alpha.FloatC(); var redF = red.FloatC(); var greenF = green.FloatC(); + var blueF = blue.FloatC(); + + // Act + var color = new Argb([alphaF, redF, greenF, blueF]); + + // Assert + Assert.Equal(alphaF, color.A); + Assert.Equal(redF, color.R); + Assert.Equal(greenF, color.G); + Assert.Equal(blueF, color.B); + + // Act & Assert + Assert.Throws(() => new Argb([redF, greenF, blueF])); + Assert.Throws(() => new Argb([alphaF, redF, greenF, blueF, alphaF])); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void ArgbT_CopyTo(byte alpha, byte red, byte green, byte blue) + { + { + // Arrange + var color = new Argb(alpha, red, green, blue); + var destination = new byte[6]; + + // Act + color.CopyTo(destination.AsSpan(1, 4)); + + // Assert + Assert.Equal(default, destination[0]); + Assert.Equal(alpha, destination[1]); + Assert.Equal(red, destination[2]); + Assert.Equal(green, destination[3]); + Assert.Equal(blue, destination[4]); + Assert.Equal(default, destination[5]); + + // Act & Assert + Assert.Throws(() => color.CopyTo(null)); + Assert.Throws(() => color.CopyTo(default)); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 3))); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 5))); + } + + { + // Arrange + var alphaF = alpha.FloatC(); var redF = red.FloatC(); var greenF = green.FloatC(); + var blueF = blue.FloatC(); + var color = new Argb(alphaF, redF, greenF, blueF); + var destination = new float[6]; + + // Act + color.CopyTo(destination.AsSpan(1, 4)); + + // Assert + Assert.Equal(default, destination[0]); + Assert.Equal(alphaF, destination[1]); + Assert.Equal(redF, destination[2]); + Assert.Equal(greenF, destination[3]); + Assert.Equal(blueF, destination[4]); + Assert.Equal(default, destination[5]); + + // Act & Assert + Assert.Throws(() => color.CopyTo(null)); + Assert.Throws(() => color.CopyTo(default)); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 3))); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 5))); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColorsTwoTimes), MemberType = typeof(TestHelpers))] + public void ArgbT_Equals((byte, byte, byte, byte) c1, (byte, byte, byte, byte) c2) + { + { + // Arrange + var color1 = new Argb(c1.Item1, c1.Item2, c1.Item3, c1.Item4); + var color2 = new Argb(c2.Item1, c2.Item2, c2.Item3, c2.Item4); + var color3 = new Argb((byte)(c1.Item1 + 111), (byte)(c1.Item2 + 222), (byte)(c1.Item3 + 333), + (byte)(c1.Item4 + 444)); + + // Act & Assert + if (c1 == c2) + { + Assert.True(color1.Equals(color2)); + Assert.True(color1.Equals((object)color2)); + Assert.True(((object)color1).Equals(color2)); + + Assert.True(color2.Equals(color1)); + Assert.True(color2.Equals((object)color1)); + Assert.True(((object)color2).Equals(color1)); + } + else + { + Assert.False(color1.Equals(color2)); + Assert.False(color1.Equals((object)color2)); + Assert.False(((object)color1).Equals(color2)); + + Assert.False(color2.Equals(color1)); + Assert.False(color2.Equals((object)color1)); + Assert.False(((object)color2).Equals(color1)); + } + + Assert.True(color1.Equals(color1)); + Assert.True(color1.Equals((object)color1)); + + Assert.False(color1.Equals(color1 with { A = color3.A })); + Assert.False(color1.Equals((object)(color1 with { A = color3.A }))); + Assert.False(color1.Equals(color1 with { R = color3.R })); + Assert.False(color1.Equals((object)(color1 with { R = color3.R }))); + Assert.False(color1.Equals(color1 with { G = color3.G })); + Assert.False(color1.Equals((object)(color1 with { G = color3.G }))); + Assert.False(color1.Equals(color1 with { B = color3.B })); + Assert.False(color1.Equals((object)(color1 with { B = color3.B }))); + + Assert.False(color1.Equals(null)); + } + + { + // Arrange + var color1 = new Argb(c1.Item1.FloatC(), c1.Item2.FloatC(), c1.Item3.FloatC(), c1.Item4.FloatC()); + var color2 = new Argb(c2.Item1.FloatC(), c2.Item2.FloatC(), c2.Item3.FloatC(), c2.Item4.FloatC()); + var color3 = new Argb(((byte)(c1.Item1 + 111)).FloatC(), ((byte)(c1.Item2 + 222)).FloatC(), + ((byte)(c1.Item3 + 333)).FloatC(), ((byte)(c1.Item4 + 444)).FloatC()); + + // Act & Assert + if (c1 == c2) + { + Assert.True(color1.Equals(color2)); + Assert.True(color1.Equals((object)color2)); + Assert.True(((object)color1).Equals(color2)); + + Assert.True(color2.Equals(color1)); + Assert.True(color2.Equals((object)color1)); + Assert.True(((object)color2).Equals(color1)); + } + else + { + Assert.False(color1.Equals(color2)); + Assert.False(color1.Equals((object)color2)); + Assert.False(((object)color1).Equals(color2)); + + Assert.False(color2.Equals(color1)); + Assert.False(color2.Equals((object)color1)); + Assert.False(((object)color2).Equals(color1)); + } + + Assert.True(color1.Equals(color1)); + Assert.True(color1.Equals((object)color1)); + + Assert.False(color1.Equals(color1 with { A = color3.A })); + Assert.False(color1.Equals(color1 with { R = color3.R })); + Assert.False(color1.Equals(color1 with { G = color3.G })); + Assert.False(color1.Equals(color1 with { B = color3.B })); + Assert.False(color1.Equals((object)(color1 with { A = color3.A }))); + Assert.False(color1.Equals((object)(color1 with { R = color3.R }))); + Assert.False(color1.Equals((object)(color1 with { G = color3.G }))); + Assert.False(color1.Equals((object)(color1 with { B = color3.B }))); + + Assert.False(color1.Equals(null)); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColorsTwoTimes), MemberType = typeof(TestHelpers))] + public void ArgbT_GetHashCode((byte, byte, byte, byte) c1, (byte, byte, byte, byte) c2) + { + { + // Arrange + var color1 = new Argb(c1.Item1, c1.Item2, c1.Item3, c1.Item4); + var color2 = new Argb(c2.Item1, c2.Item2, c2.Item3, c2.Item4); + var color3 = new Argb((byte)(c1.Item1 + 111), (byte)(c1.Item2 + 222), (byte)(c1.Item3 + 333), + (byte)(c1.Item4 + 444)); + + // Act & Assert + if (c1 == c2) + { + Assert.Equal(color1.GetHashCode(), color2.GetHashCode()); + } + else + { + Assert.NotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + Assert.Equal(color1.GetHashCode(), color1.GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { A = color3.A }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { R = color3.R }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { G = color3.G }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { B = color3.B }).GetHashCode()); + } + + { + // Arrange + var color1 = new Argb(c1.Item1.FloatC(), c1.Item2.FloatC(), c1.Item3.FloatC(), c1.Item4.FloatC()); + var color2 = new Argb(c2.Item1.FloatC(), c2.Item2.FloatC(), c2.Item3.FloatC(), c2.Item4.FloatC()); + var color3 = new Argb(((byte)(c1.Item1 + 111)).FloatC(), ((byte)(c1.Item2 + 222)).FloatC(), + ((byte)(c1.Item3 + 333)).FloatC(), ((byte)(c1.Item4 + 444)).FloatC()); + + // Act & Assert + if (c1 == c2) + { + Assert.Equal(color1.GetHashCode(), color2.GetHashCode()); + } + else + { + Assert.NotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + Assert.Equal(color1.GetHashCode(), color1.GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { A = color3.A }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { R = color3.R }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { G = color3.G }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { B = color3.B }).GetHashCode()); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void ArgbT_ToString(byte alpha, byte red, byte green, byte blue) + { + { + // Arrange + var color = new Argb(alpha, red, green, blue); + + // Act & Assert + Assert.Equal($"[ARGB Color: {alpha}, {red}, {green}, {blue}]", color.ToString()); + } + + { + // Arrange + var alphaF = alpha.FloatC(); var redF = red.FloatC(); var greenF = green.FloatC(); + var blueF = blue.FloatC(); + var color = new Argb(alphaF, redF, greenF, blueF); + + // Act & Assert + Assert.Equal($"[ARGB Color: {alphaF}, {redF}, {greenF}, {blueF}]", color.ToString()); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void ArgbT_ToRgba(byte alpha, byte red, byte green, byte blue) + { + { + // Arrange + var color = new Argb(alpha, red, green, blue); + var expected = new Rgba(red, green, blue, alpha); + + // Act & Assert + Assert.Equal(expected, color.ToRgba()); + } + + { + // Arrange + var alphaF = alpha.FloatC(); var redF = red.FloatC(); var greenF = green.FloatC(); + var blueF = blue.FloatC(); + var color = new Argb(alphaF, redF, greenF, blueF); + var expected = new Rgba(redF, greenF, blueF, alphaF); + + // Act & Assert + Assert.Equal(expected, color.ToRgba()); + } + } + } +} diff --git a/src/libraries/System.Numerics.Colors/tests/Rgba.T.Tests.cs b/src/libraries/System.Numerics.Colors/tests/Rgba.T.Tests.cs new file mode 100644 index 00000000000000..9bd01a97a55080 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/Rgba.T.Tests.cs @@ -0,0 +1,407 @@ +using Xunit; + +namespace System.Numerics.Colors.Tests +{ + public class RgbaTTests + { + [Fact] + public void RgbaT_Default() + { + { + // Act + Rgba color = default; + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Rgba color = new(default, default, default, default); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Rgba color = new([default, default, default, default]); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act & Assert + Assert.Throws(() => new Rgba(null)); + Assert.Throws(() => new Rgba(default)); + Assert.Throws(() => new Rgba([default, default, default])); + Assert.Throws(() => new Rgba([default, default, default, default, default])); + } + + { + // Act + Rgba color = default; + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Rgba color = new(default, default, default, default); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act + Rgba color = new([default, default, default, default]); + + // Assert + Assert.Equal(default, color.A); + Assert.Equal(default, color.R); + Assert.Equal(default, color.G); + Assert.Equal(default, color.B); + } + { + // Act & Assert + Assert.Throws(() => new Rgba(null)); + Assert.Throws(() => new Rgba(default)); + Assert.Throws(() => new Rgba([default, default, default])); + Assert.Throws(() => new Rgba([default, default, default, default, default])); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void RgbaT_CtorRgba(byte red, byte green, byte blue, byte alpha) + { + { + // Act + var color = new Rgba(red, green, blue, alpha); + + // Assert + Assert.Equal(red, color.R); + Assert.Equal(green, color.G); + Assert.Equal(blue, color.B); + Assert.Equal(alpha, color.A); + } + + { + // Arrange + var redF = red.FloatC(); var greenF = green.FloatC(); var blueF = blue.FloatC(); + var alphaF = alpha.FloatC(); + + // Act + var color = new Rgba(redF, greenF, blueF, alphaF); + + // Assert + Assert.Equal(redF, color.R); + Assert.Equal(greenF, color.G); + Assert.Equal(blueF, color.B); + Assert.Equal(alphaF, color.A); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void RgbaT_CtorSpan(byte red, byte green, byte blue, byte alpha) + { + { + // Arrange + byte[] values = [default, red, green, blue, alpha, default]; + + // Act + var color = new Rgba(values.AsSpan(1, 4)); + + // Assert + Assert.Equal(red, color.R); + Assert.Equal(green, color.G); + Assert.Equal(blue, color.B); + Assert.Equal(alpha, color.A); + + // Act & Assert + Assert.Throws(() => new Rgba([red, green, blue])); + Assert.Throws(() => new Rgba([red, green, blue, alpha, red])); + } + + { + // Arrange + var redF = red.FloatC(); var greenF = green.FloatC(); var blueF = blue.FloatC(); + var alphaF = alpha.FloatC(); + + // Act + var color = new Rgba([redF, greenF, blueF, alphaF]); + + // Assert + Assert.Equal(redF, color.R); + Assert.Equal(greenF, color.G); + Assert.Equal(blueF, color.B); + Assert.Equal(alphaF, color.A); + + // Act & Assert + Assert.Throws(() => new Rgba([redF, greenF, blueF])); + Assert.Throws(() => new Rgba([redF, greenF, blueF, alphaF, redF])); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void RgbaT_CopyTo(byte red, byte green, byte blue, byte alpha) + { + { + // Arrange + var color = new Rgba(red, green, blue, alpha); + var destination = new byte[6]; + + // Act + color.CopyTo(destination.AsSpan(1, 4)); + + // Assert + Assert.Equal(default, destination[0]); + Assert.Equal(red, destination[1]); + Assert.Equal(green, destination[2]); + Assert.Equal(blue, destination[3]); + Assert.Equal(alpha, destination[4]); + Assert.Equal(default, destination[5]); + + // Act & Assert + Assert.Throws(() => color.CopyTo(null)); + Assert.Throws(() => color.CopyTo(default)); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 3))); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 5))); + } + + { + // Arrange + var redF = red.FloatC(); var greenF = green.FloatC(); var blueF = blue.FloatC(); + var alphaF = alpha.FloatC(); + var color = new Rgba(redF, greenF, blueF, alphaF); + var destination = new float[6]; + + // Act + color.CopyTo(destination.AsSpan(1, 4)); + + // Assert + Assert.Equal(default, destination[0]); + Assert.Equal(redF, destination[1]); + Assert.Equal(greenF, destination[2]); + Assert.Equal(blueF, destination[3]); + Assert.Equal(alphaF, destination[4]); + Assert.Equal(default, destination[5]); + + // Act & Assert + Assert.Throws(() => color.CopyTo(null)); + Assert.Throws(() => color.CopyTo(default)); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 3))); + Assert.Throws(() => color.CopyTo(destination.AsSpan(1, 5))); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColorsTwoTimes), MemberType = typeof(TestHelpers))] + public void RgbaT_Equals((byte, byte, byte, byte) c1, (byte, byte, byte, byte) c2) + { + { + // Arrange + var color1 = new Rgba(c1.Item1, c1.Item2, c1.Item3, c1.Item4); + var color2 = new Rgba(c2.Item1, c2.Item2, c2.Item3, c2.Item4); + var color3 = new Rgba((byte)(c1.Item1 + 111), (byte)(c1.Item2 + 222), (byte)(c1.Item3 + 333), + (byte)(c1.Item4 + 444)); + + // Act & Assert + if (c1 == c2) + { + Assert.True(color1.Equals(color2)); + Assert.True(color1.Equals((object)color2)); + Assert.True(((object)color1).Equals(color2)); + + Assert.True(color2.Equals(color1)); + Assert.True(color2.Equals((object)color1)); + Assert.True(((object)color2).Equals(color1)); + } + else + { + Assert.False(color1.Equals(color2)); + Assert.False(color1.Equals((object)color2)); + Assert.False(((object)color1).Equals(color2)); + + Assert.False(color2.Equals(color1)); + Assert.False(color2.Equals((object)color1)); + Assert.False(((object)color2).Equals(color1)); + } + + Assert.True(color1.Equals(color1)); + Assert.True(color1.Equals((object)color1)); + + Assert.False(color1.Equals(color1 with { R = color3.R })); + Assert.False(color1.Equals((object)(color1 with { R = color3.R }))); + Assert.False(color1.Equals(color1 with { G = color3.G })); + Assert.False(color1.Equals((object)(color1 with { G = color3.G }))); + Assert.False(color1.Equals(color1 with { B = color3.B })); + Assert.False(color1.Equals((object)(color1 with { B = color3.B }))); + Assert.False(color1.Equals(color1 with { A = color3.A })); + Assert.False(color1.Equals((object)(color1 with { A = color3.A }))); + + Assert.False(color1.Equals(null)); + } + + { + // Arrange + var color1 = new Rgba(c1.Item1.FloatC(), c1.Item2.FloatC(), c1.Item3.FloatC(), c1.Item4.FloatC()); + var color2 = new Rgba(c2.Item1.FloatC(), c2.Item2.FloatC(), c2.Item3.FloatC(), c2.Item4.FloatC()); + var color3 = new Rgba(((byte)(c1.Item1 + 111)).FloatC(), ((byte)(c1.Item2 + 222)).FloatC(), + ((byte)(c1.Item3 + 333)).FloatC(), ((byte)(c1.Item4 + 444)).FloatC()); + + // Act & Assert + if (c1 == c2) + { + Assert.True(color1.Equals(color2)); + Assert.True(color1.Equals((object)color2)); + Assert.True(((object)color1).Equals(color2)); + + Assert.True(color2.Equals(color1)); + Assert.True(color2.Equals((object)color1)); + Assert.True(((object)color2).Equals(color1)); + } + else + { + Assert.False(color1.Equals(color2)); + Assert.False(color1.Equals((object)color2)); + Assert.False(((object)color1).Equals(color2)); + + Assert.False(color2.Equals(color1)); + Assert.False(color2.Equals((object)color1)); + Assert.False(((object)color2).Equals(color1)); + } + + Assert.True(color1.Equals(color1)); + Assert.True(color1.Equals((object)color1)); + + Assert.False(color1.Equals(color1 with { R = color3.R })); + Assert.False(color1.Equals(color1 with { G = color3.G })); + Assert.False(color1.Equals(color1 with { B = color3.B })); + Assert.False(color1.Equals(color1 with { A = color3.A })); + Assert.False(color1.Equals((object)(color1 with { R = color3.R }))); + Assert.False(color1.Equals((object)(color1 with { G = color3.G }))); + Assert.False(color1.Equals((object)(color1 with { B = color3.B }))); + Assert.False(color1.Equals((object)(color1 with { A = color3.A }))); + + Assert.False(color1.Equals(null)); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColorsTwoTimes), MemberType = typeof(TestHelpers))] + public void RgbaT_GetHashCode((byte, byte, byte, byte) c1, (byte, byte, byte, byte) c2) + { + { + // Arrange + var color1 = new Rgba(c1.Item1, c1.Item2, c1.Item3, c1.Item4); + var color2 = new Rgba(c2.Item1, c2.Item2, c2.Item3, c2.Item4); + var color3 = new Rgba((byte)(c1.Item1 + 111), (byte)(c1.Item2 + 222), (byte)(c1.Item3 + 333), + (byte)(c1.Item4 + 444)); + + // Act & Assert + if (c1 == c2) + { + Assert.Equal(color1.GetHashCode(), color2.GetHashCode()); + } + else + { + Assert.NotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + Assert.Equal(color1.GetHashCode(), color1.GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { R = color3.R }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { G = color3.G }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { B = color3.B }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { A = color3.A }).GetHashCode()); + } + + { + // Arrange + var color1 = new Rgba(c1.Item1.FloatC(), c1.Item2.FloatC(), c1.Item3.FloatC(), c1.Item4.FloatC()); + var color2 = new Rgba(c2.Item1.FloatC(), c2.Item2.FloatC(), c2.Item3.FloatC(), c2.Item4.FloatC()); + var color3 = new Rgba(((byte)(c1.Item1 + 111)).FloatC(), ((byte)(c1.Item2 + 222)).FloatC(), + ((byte)(c1.Item3 + 333)).FloatC(), ((byte)(c1.Item4 + 444)).FloatC()); + + // Act & Assert + if (c1 == c2) + { + Assert.Equal(color1.GetHashCode(), color2.GetHashCode()); + } + else + { + Assert.NotEqual(color1.GetHashCode(), color2.GetHashCode()); + } + + Assert.Equal(color1.GetHashCode(), color1.GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { R = color3.R }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { G = color3.G }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { B = color3.B }).GetHashCode()); + Assert.NotEqual(color1.GetHashCode(), (color1 with { A = color3.A }).GetHashCode()); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void RgbaT_ToString(byte red, byte green, byte blue, byte alpha) + { + { + // Arrange + var color = new Rgba(red, green, blue, alpha); + + // Act & Assert + Assert.Equal($"[RGBA Color: {red}, {green}, {blue}, {alpha}]", color.ToString()); + } + + { + // Arrange + var redF = red.FloatC(); var greenF = green.FloatC(); var blueF = blue.FloatC(); + var alphaF = alpha.FloatC(); + var color = new Rgba(redF, greenF, blueF, alphaF); + + // Act & Assert + Assert.Equal($"[RGBA Color: {redF}, {greenF}, {blueF}, {alphaF}]", color.ToString()); + } + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void RgbaT_ToArgb(byte red, byte green, byte blue, byte alpha) + { + { + // Arrange + var color = new Rgba(red, green, blue, alpha); + var expected = new Argb(alpha, red, green, blue); + + // Act & Assert + Assert.Equal(expected, color.ToArgb()); + } + + { + // Arrange + var redF = red.FloatC(); var greenF = green.FloatC(); var blueF = blue.FloatC(); + var alphaF = alpha.FloatC(); + var color = new Rgba(redF, greenF, blueF, alphaF); + var expected = new Argb(alphaF, redF, greenF, blueF); + + // Act & Assert + Assert.Equal(expected, color.ToArgb()); + } + } + } +} diff --git a/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj b/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj new file mode 100644 index 00000000000000..0fe3571ee46d97 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj @@ -0,0 +1,19 @@ + + + + $(NetCoreAppCurrent) + enable + enable + + + + + + + + + + + + + diff --git a/src/libraries/System.Numerics.Colors/tests/TestHelpers.cs b/src/libraries/System.Numerics.Colors/tests/TestHelpers.cs new file mode 100644 index 00000000000000..ed1aecab1ace11 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/TestHelpers.cs @@ -0,0 +1,54 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Collections.Generic; +using System.Drawing; +using Microsoft.DotNet.XUnitExtensions; +using Xunit; +using static System.Runtime.InteropServices.JavaScript.JSType; + +namespace System.Numerics.Colors.Tests +{ + public static class TestHelpers + { + public static IReadOnlyList<(byte, byte, byte, byte)> ByteColorsList = + [ + ( 0, 0, 0, 0 ), + + ( 111, 222, 77, 188 ), + ( 43, 222, 77, 188 ), + ( 111, 154, 77, 188 ), + ( 111, 222, 9, 188 ), + ( 111, 222, 77, 120 ), + + ( 255, 255, 255, 255 ), + ]; + + public static TheoryData ByteColors + { + get + { + var data = new TheoryData(); + foreach (var color in ByteColorsList) + data.Add(color.Item1, color.Item2, color.Item3, color.Item3); + return data; + } + } + + + public static TheoryData<(byte, byte, byte, byte), (byte, byte, byte, byte)> ByteColorsTwoTimes + { + get + { + var ColorsTwoTimes = ByteColorsList.SelectMany(color => ByteColorsList, (color1, color2) => (color1, color2)); + var data = new TheoryData<(byte, byte, byte, byte), (byte, byte, byte, byte)>(); + foreach (var twoColors in ColorsTwoTimes) + data.Add(twoColors.color1, twoColors.color2); + return data; + } + } + + public static float FloatC(this T colorComponent) where T : IBinaryInteger, IMinMaxValue + => Math.Clamp(float.CreateChecked(colorComponent) / float.CreateChecked(T.MaxValue), 0f, 1f); + } +} diff --git a/src/libraries/shims/netstandard/src/netstandard.csproj b/src/libraries/shims/netstandard/src/netstandard.csproj index 6db125b88f56a6..c1e6c75d45d4c4 100644 --- a/src/libraries/shims/netstandard/src/netstandard.csproj +++ b/src/libraries/shims/netstandard/src/netstandard.csproj @@ -57,6 +57,7 @@ + diff --git a/src/tests/Common/scripts/crossgen2_comparison.py b/src/tests/Common/scripts/crossgen2_comparison.py index 65b0e062726a0e..fa9c840882f5e5 100644 --- a/src/tests/Common/scripts/crossgen2_comparison.py +++ b/src/tests/Common/scripts/crossgen2_comparison.py @@ -403,6 +403,7 @@ def run_to_completion(self, async_callback, *extra_args): 'System.Net.WebSockets.Client.dll', 'System.Net.WebSockets.dll', 'System.Numerics.dll', + 'System.Numerics.Colors.dll', 'System.Numerics.Tensors.dll', 'System.Numerics.Vectors.dll', 'System.ObjectModel.dll', From d7801be91cb41ea12983f1e5dce8835580e64808 Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Sun, 18 Aug 2024 00:38:34 +0700 Subject: [PATCH 2/3] System.Drawing.Primitives --- ...System.ComponentModel.TypeConverter.csproj | 1 + .../ref/System.Drawing.Primitives.cs | 4 + .../ref/System.Drawing.Primitives.csproj | 1 + .../src/System.Drawing.Primitives.csproj | 1 + .../src/System/Drawing/Color.cs | 21 +++++- .../tests/ColorTests.cs | 75 +++++++++++++++---- .../tests/ColorTranslatorTests.cs | 2 +- .../tests/PointFTests.cs | 2 +- .../tests/PointTests.cs | 2 +- .../tests/RectangleFTests.cs | 2 +- .../tests/RectangleTests.cs | 2 +- .../tests/SizeFTests.cs | 2 +- .../tests/SizeTests.cs | 2 +- 13 files changed, 91 insertions(+), 26 deletions(-) diff --git a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj index 6979742610c466..f932a936dd5574 100644 --- a/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj +++ b/src/libraries/System.ComponentModel.TypeConverter/src/System.ComponentModel.TypeConverter.csproj @@ -259,6 +259,7 @@ + diff --git a/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs b/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs index 4ab096f9be6245..7092917d2fe479 100644 --- a/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs +++ b/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.cs @@ -167,6 +167,7 @@ namespace System.Drawing public bool Equals(System.Drawing.Color other) { throw null; } public override bool Equals([System.Diagnostics.CodeAnalysis.NotNullWhenAttribute(true)] object? obj) { throw null; } public static System.Drawing.Color FromArgb(int argb) { throw null; } + public static System.Drawing.Color FromArgb(System.Numerics.Colors.Argb argb) { throw null; } public static System.Drawing.Color FromArgb(int alpha, System.Drawing.Color baseColor) { throw null; } public static System.Drawing.Color FromArgb(int red, int green, int blue) { throw null; } public static System.Drawing.Color FromArgb(int alpha, int red, int green, int blue) { throw null; } @@ -178,7 +179,10 @@ namespace System.Drawing public float GetSaturation() { throw null; } public static bool operator ==(System.Drawing.Color left, System.Drawing.Color right) { throw null; } public static bool operator !=(System.Drawing.Color left, System.Drawing.Color right) { throw null; } + public static explicit operator System.Numerics.Colors.Argb(in System.Drawing.Color color) { throw null; } + public static implicit operator System.Drawing.Color(System.Numerics.Colors.Argb argb) { throw null; } public int ToArgb() { throw null; } + public System.Numerics.Colors.Argb ToArgbValue() { throw null; } public System.Drawing.KnownColor ToKnownColor() { throw null; } public override string ToString() { throw null; } } diff --git a/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.csproj b/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.csproj index b2a2d407f727f9..7b218d076db2a9 100644 --- a/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.csproj +++ b/src/libraries/System.Drawing.Primitives/ref/System.Drawing.Primitives.csproj @@ -9,6 +9,7 @@ + \ No newline at end of file diff --git a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj index 58b5852c2c916f..24de1056a80644 100644 --- a/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj +++ b/src/libraries/System.Drawing.Primitives/src/System.Drawing.Primitives.csproj @@ -49,6 +49,7 @@ + diff --git a/src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs b/src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs index c588679d872133..b7827c037e76b8 100644 --- a/src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs +++ b/src/libraries/System.Drawing.Primitives/src/System/Drawing/Color.cs @@ -4,6 +4,7 @@ using System.ComponentModel; using System.Diagnostics; using System.Diagnostics.CodeAnalysis; +using System.Numerics.Colors; using System.Runtime.CompilerServices; namespace System.Drawing @@ -333,7 +334,7 @@ namespace System.Drawing internal const uint ARGBBlueMask = 0xFFu << ARGBBlueShift; // User supplied name of color. Will not be filled in if - // we map to a "knowncolor" + // we map to a "knownColor" private readonly string? name; // Do not rename (binary serialization) // Standard 32bit sRGB (ARGB) @@ -398,10 +399,10 @@ public string Name if (IsKnownColor) { - string tablename = KnownColorNames.KnownColorToName((KnownColor)knownColor); - Debug.Assert(tablename != null, $"Could not find known color '{(KnownColor)knownColor}' in the KnownColorTable"); + string tableName = KnownColorNames.KnownColorToName((KnownColor)knownColor); + Debug.Assert(tableName != null, $"Could not find known color '{(KnownColor)knownColor}' in the KnownColorTable"); - return tablename; + return tableName; } // if we reached here, just encode the value @@ -442,6 +443,10 @@ static void ThrowOutOfByteRange(int v, string n) => public static Color FromArgb(int argb) => FromArgb(unchecked((uint)argb)); + public static Color FromArgb(Argb argb) => FromArgb(BitConverter.IsLittleEndian ? + Argb.ToUInt32LittleEndian(argb) : + Argb.ToUInt32BigEndian(argb)); + public static Color FromArgb(int alpha, int red, int green, int blue) { CheckByte(alpha, nameof(alpha)); @@ -567,6 +572,10 @@ public float GetSaturation() public int ToArgb() => unchecked((int)Value); + public Argb ToArgbValue() => BitConverter.IsLittleEndian ? + Argb.CreateLittleEndian(unchecked((uint)Value)) : + Argb.CreateBigEndian(unchecked((uint)Value)); + public KnownColor ToKnownColor() => (KnownColor)knownColor; public override string ToString() => @@ -582,6 +591,10 @@ public override string ToString() => public static bool operator !=(Color left, Color right) => !(left == right); + public static implicit operator Color(Argb argb) => FromArgb(argb); + + public static explicit operator Argb(in Color color) => color.ToArgbValue(); + public override bool Equals([NotNullWhen(true)] object? obj) => obj is Color other && Equals(other); public bool Equals(Color other) => this == other; diff --git a/src/libraries/System.Drawing.Primitives/tests/ColorTests.cs b/src/libraries/System.Drawing.Primitives/tests/ColorTests.cs index a4a674d9b517b3..8ab1f0e88f3b75 100644 --- a/src/libraries/System.Drawing.Primitives/tests/ColorTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/ColorTests.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using System.Numerics.Colors; using System.Runtime.InteropServices; using Xunit; @@ -194,23 +195,45 @@ public void ArgbValues(string name, int alpha, int red, int green, int blue) [InlineData(1, 2, 3, 4)] public void FromArgb_Roundtrips(int a, int r, int g, int b) { - Color c1 = Color.FromArgb(unchecked((int)((uint)a << 24 | (uint)r << 16 | (uint)g << 8 | (uint)b))); - Assert.Equal(a, c1.A); - Assert.Equal(r, c1.R); - Assert.Equal(g, c1.G); - Assert.Equal(b, c1.B); + { + Color c = Color.FromArgb(unchecked((int)((uint)a << 24 | (uint)r << 16 | (uint)g << 8 | (uint)b))); + Assert.Equal(a, c.A); + Assert.Equal(r, c.R); + Assert.Equal(g, c.G); + Assert.Equal(b, c.B); + } + { + Color c = Color.FromArgb(a, r, g, b); + Assert.Equal(a, c.A); + Assert.Equal(r, c.R); + Assert.Equal(g, c.G); + Assert.Equal(b, c.B); + } + { - Color c2 = Color.FromArgb(a, r, g, b); - Assert.Equal(a, c2.A); - Assert.Equal(r, c2.R); - Assert.Equal(g, c2.G); - Assert.Equal(b, c2.B); + Color c = Color.FromArgb(r, g, b); + Assert.Equal(255, c.A); + Assert.Equal(r, c.R); + Assert.Equal(g, c.G); + Assert.Equal(b, c.B); + } + { + + Color c = Color.FromArgb(new Argb((byte)a, (byte)r, (byte)g, (byte)b)); + Assert.Equal(a, c.A); + Assert.Equal(r, c.R); + Assert.Equal(g, c.G); + Assert.Equal(b, c.B); + } + { - Color c3 = Color.FromArgb(r, g, b); - Assert.Equal(255, c3.A); - Assert.Equal(r, c3.R); - Assert.Equal(g, c3.G); - Assert.Equal(b, c3.B); + // implicit operator Color(Argb argb) + Color c = new Argb((byte)a, (byte)r, (byte)g, (byte)b); + Assert.Equal(a, c.A); + Assert.Equal(r, c.R); + Assert.Equal(g, c.G); + Assert.Equal(b, c.B); + } } [Fact] @@ -267,6 +290,28 @@ public void ToArgb(int argb, int alpha, int red, int green, int blue) Assert.Equal(argb, Color.FromArgb(alpha, red, green, blue).ToArgb()); } + [Theory] + [InlineData(0x11, 0xcc, 0x88, 0x33)] + [InlineData(0xf1, 0xcc, 0x88, 0x33)] + public void ToArgbValue(int alpha, int red, int green, int blue) + { + { + var c = Color.FromArgb(alpha, red, green, blue).ToArgbValue(); + Assert.Equal(alpha, c.A); + Assert.Equal(red, c.R); + Assert.Equal(green, c.G); + Assert.Equal(blue, c.B); + } + { + // explicit operator Argb(in Color color) + Argb c = (Argb)Color.FromArgb(alpha, red, green, blue); + Assert.Equal(alpha, c.A); + Assert.Equal(red, c.R); + Assert.Equal(green, c.G); + Assert.Equal(blue, c.B); + } + } + [Fact] public void ToStringEmpty() { diff --git a/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs b/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs index 50bd65c0113dc0..4a94f4c356aa0d 100644 --- a/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/ColorTranslatorTests.cs @@ -8,7 +8,7 @@ using System.Threading; using Xunit; -namespace System.Drawing.Tests +namespace System.Drawing.Primitives.Tests { public class ColorTranslatorTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/PointFTests.cs b/src/libraries/System.Drawing.Primitives/tests/PointFTests.cs index 4369a729f8ed5a..13963c67fc25dc 100644 --- a/src/libraries/System.Drawing.Primitives/tests/PointFTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/PointFTests.cs @@ -6,7 +6,7 @@ using System.Reflection; using Xunit; -namespace System.Drawing.PrimitivesTests +namespace System.Drawing.Primitives.Tests { public class PointFTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/PointTests.cs b/src/libraries/System.Drawing.Primitives/tests/PointTests.cs index 76f9ac9ba80fb9..8a0b4f39aa9caa 100644 --- a/src/libraries/System.Drawing.Primitives/tests/PointTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/PointTests.cs @@ -4,7 +4,7 @@ using System.Globalization; using Xunit; -namespace System.Drawing.PrimitivesTests +namespace System.Drawing.Primitives.Tests { public class PointTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/RectangleFTests.cs b/src/libraries/System.Drawing.Primitives/tests/RectangleFTests.cs index d7803261823b87..1cbb26fdad0045 100644 --- a/src/libraries/System.Drawing.Primitives/tests/RectangleFTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/RectangleFTests.cs @@ -5,7 +5,7 @@ using System.Numerics; using Xunit; -namespace System.Drawing.PrimitivesTest +namespace System.Drawing.Primitives.Tests { public class RectangleFTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/RectangleTests.cs b/src/libraries/System.Drawing.Primitives/tests/RectangleTests.cs index e21995a1277571..8bebd05aff677f 100644 --- a/src/libraries/System.Drawing.Primitives/tests/RectangleTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/RectangleTests.cs @@ -4,7 +4,7 @@ using System.Globalization; using Xunit; -namespace System.Drawing.PrimitivesTest +namespace System.Drawing.Primitives.Tests { public class RectangleTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/SizeFTests.cs b/src/libraries/System.Drawing.Primitives/tests/SizeFTests.cs index e63179738a433a..b35b63cbe3509d 100644 --- a/src/libraries/System.Drawing.Primitives/tests/SizeFTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/SizeFTests.cs @@ -5,7 +5,7 @@ using System.Numerics; using Xunit; -namespace System.Drawing.PrimitivesTest +namespace System.Drawing.Primitives.Tests { public class SizeFTests { diff --git a/src/libraries/System.Drawing.Primitives/tests/SizeTests.cs b/src/libraries/System.Drawing.Primitives/tests/SizeTests.cs index c7eca5c8c73d7d..12c56ee60abb37 100644 --- a/src/libraries/System.Drawing.Primitives/tests/SizeTests.cs +++ b/src/libraries/System.Drawing.Primitives/tests/SizeTests.cs @@ -4,7 +4,7 @@ using System.Globalization; using Xunit; -namespace System.Drawing.PrimitivesTests +namespace System.Drawing.Primitives.Tests { public class SizeTests { From 0b69b42e6b5a306762be9f7cf9e7f4da95c3df5d Mon Sep 17 00:00:00 2001 From: Alexander Radchenko Date: Sun, 18 Aug 2024 14:23:11 +0700 Subject: [PATCH 3/3] Argb.Tests Rgba.Tests --- .../src/System/Numerics/Colors/Argb.cs | 14 ++-- .../tests/Argb.Tests.cs | 64 +++++++++++++++++++ .../tests/Rgba.Tests.cs | 64 +++++++++++++++++++ .../tests/System.Numerics.Colors.Tests.csproj | 2 + 4 files changed, 135 insertions(+), 9 deletions(-) create mode 100644 src/libraries/System.Numerics.Colors/tests/Argb.Tests.cs create mode 100644 src/libraries/System.Numerics.Colors/tests/Rgba.Tests.cs diff --git a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs index db9e8721783da7..ee8f4a1ed2f559 100644 --- a/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs +++ b/src/libraries/System.Numerics.Colors/src/System/Numerics/Colors/Argb.cs @@ -27,11 +27,8 @@ public static class Argb /// /// A little-endian representing an ARGB color. /// An new instance of the color. - public static Argb CreateLittleEndian(uint color) - { - color = BinaryPrimitives.ReverseEndianness(color); - return Unsafe.As>(ref color); - } + public static Argb CreateLittleEndian(uint color) => + CreateBigEndian(BinaryPrimitives.ReverseEndianness(color)); /// /// Converts the specified color to a big-endian representing an @@ -39,8 +36,7 @@ public static Argb CreateLittleEndian(uint color) /// /// The color to convert. /// A big-endian representing an ARGB color. - public static uint ToUInt32BigEndian(this Argb color) - => Unsafe.As, uint>(ref color); + public static uint ToUInt32BigEndian(this Argb color) => Unsafe.As, uint>(ref color); /// /// Converts the specified color to a little-endian representing @@ -48,8 +44,8 @@ public static uint ToUInt32BigEndian(this Argb color) /// /// The color to convert. /// A little-endian representing an ARGB color. - public static uint ToUInt32LittleEndian(this Argb color) - => BinaryPrimitives.ReverseEndianness(Unsafe.As, uint>(ref color)); + public static uint ToUInt32LittleEndian(this Argb color) => + BinaryPrimitives.ReverseEndianness(color.ToUInt32BigEndian()); } #pragma warning restore CS3001 // Argument type is not CLS-compliant diff --git a/src/libraries/System.Numerics.Colors/tests/Argb.Tests.cs b/src/libraries/System.Numerics.Colors/tests/Argb.Tests.cs new file mode 100644 index 00000000000000..f7e890d15056d2 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/Argb.Tests.cs @@ -0,0 +1,64 @@ +using System.Buffers.Binary; +using Xunit; + +namespace System.Numerics.Colors.Tests +{ + public class ArgbTests + { + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Argb_CreateBigEndian(byte alpha, byte red, byte green, byte blue) + { + // Arrange + Argb expected = new Argb(alpha, red, green, blue); + uint color = (((uint)alpha << 8 | red) << 8 | green) << 8 | blue; + if (BitConverter.IsLittleEndian) + color = BinaryPrimitives.ReverseEndianness(color); + + // Act & Assert + Assert.Equal(expected, Argb.CreateBigEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Argb_CreateLittleEndian(byte alpha, byte red, byte green, byte blue) + { + // Arrange + Argb expected = new Argb(alpha, red, green, blue); + uint color = (((uint)alpha << 8 | red) << 8 | green) << 8 | blue; + if (!BitConverter.IsLittleEndian) + color = BinaryPrimitives.ReverseEndianness(color); + + // Act & Assert + Assert.Equal(expected, Argb.CreateLittleEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Argb_ToUInt32BigEndian(byte alpha, byte red, byte green, byte blue) + { + // Arrange + uint expected = (((uint)alpha << 8 | red) << 8 | green) << 8 | blue; + if (BitConverter.IsLittleEndian) + expected = BinaryPrimitives.ReverseEndianness(expected); + Argb color = new Argb(alpha, red, green, blue); + + // Act & Assert + Assert.Equal(expected, Argb.ToUInt32BigEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Argb_ToUInt32LittleEndian(byte alpha, byte red, byte green, byte blue) + { + // Arrange + uint expected = (((uint)alpha << 8 | red) << 8 | green) << 8 | blue; + if (!BitConverter.IsLittleEndian) + expected = BinaryPrimitives.ReverseEndianness(expected); + Argb color = new Argb(alpha, red, green, blue); + + // Act & Assert + Assert.Equal(expected, Argb.ToUInt32LittleEndian(color)); + } + } +} diff --git a/src/libraries/System.Numerics.Colors/tests/Rgba.Tests.cs b/src/libraries/System.Numerics.Colors/tests/Rgba.Tests.cs new file mode 100644 index 00000000000000..54f01b09fb0861 --- /dev/null +++ b/src/libraries/System.Numerics.Colors/tests/Rgba.Tests.cs @@ -0,0 +1,64 @@ +using System.Buffers.Binary; +using Xunit; + +namespace System.Numerics.Colors.Tests +{ + public class RgbaTests + { + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Rgba_CreateBigEndian(byte red, byte green, byte blue, byte alpha) + { + // Arrange + Rgba expected = new Rgba(red, green, blue, alpha); + uint color = (((uint)red << 8 | green) << 8 | blue) << 8 | alpha; + if (BitConverter.IsLittleEndian) + color = BinaryPrimitives.ReverseEndianness(color); + + // Act & Assert + Assert.Equal(expected, Rgba.CreateBigEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Rgba_CreateLittleEndian(byte red, byte green, byte blue, byte alpha) + { + // Arrange + Rgba expected = new Rgba(red, green, blue, alpha); + uint color = (((uint)red << 8 | green) << 8 | blue) << 8 | alpha; + if (!BitConverter.IsLittleEndian) + color = BinaryPrimitives.ReverseEndianness(color); + + // Act & Assert + Assert.Equal(expected, Rgba.CreateLittleEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Rgba_ToUInt32BigEndian(byte red, byte green, byte blue, byte alpha) + { + // Arrange + uint expected = (((uint)red << 8 | green) << 8 | blue) << 8 | alpha; + if (BitConverter.IsLittleEndian) + expected = BinaryPrimitives.ReverseEndianness(expected); + Rgba color = new Rgba(red, green, blue, alpha); + + // Act & Assert + Assert.Equal(expected, Rgba.ToUInt32BigEndian(color)); + } + + [Theory] + [MemberData(nameof(TestHelpers.ByteColors), MemberType = typeof(TestHelpers))] + public void Rgba_ToUInt32LittleEndian(byte red, byte green, byte blue, byte alpha) + { + // Arrange + uint expected = (((uint)red << 8 | green) << 8 | blue) << 8 | alpha; + if (!BitConverter.IsLittleEndian) + expected = BinaryPrimitives.ReverseEndianness(expected); + Rgba color = new Rgba(red, green, blue, alpha); + + // Act & Assert + Assert.Equal(expected, Rgba.ToUInt32LittleEndian(color)); + } + } +} diff --git a/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj b/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj index 0fe3571ee46d97..470b02ca2cfff9 100644 --- a/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj +++ b/src/libraries/System.Numerics.Colors/tests/System.Numerics.Colors.Tests.csproj @@ -8,7 +8,9 @@ + +