Brought in Xamarin.Forms unit tests for colors.

This commit is contained in:
Jon Lipsky 2021-01-13 16:00:22 -08:00
Родитель 658c85543c
Коммит 2d1f03d3c1
5 изменённых файлов: 456 добавлений и 39 удалений

Просмотреть файл

@ -11,17 +11,19 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Graphics.Skia", "..\
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{9E4B772B-D417-4147-B8B1-FD9E3B0B4EC5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{D6F0522F-3BB5-4A10-953F-CA047F3D881A}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{2BAF0999-6876-4091-9FCE-CBC56D80BEC3}"
ProjectSection(SolutionItems) = preProject
.editorconfig = ..\.editorconfig
.editorconfig = .editorconfig
EndProjectSection
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Graphics.Forms", "..\src\System.Graphics.Forms\System.Graphics.Forms.csproj", "{05D753E7-C4B3-4DA7-97E0-66E5FF695F42}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Graphics.Skia.Forms", "..\src\System.Graphics.Skia.Forms\System.Graphics.Skia.Forms.csproj", "{BD41610F-2F5B-40BA-AAC4-5F7EEBDC462C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Graphics.Tests", "..\tests\System.Graphics.Tests\System.Graphics.Tests.csproj", "{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8A2197EB-6E30-495D-9DE9-2E40032FB2E9}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
..\src\System.Graphics.SharpDX.Shared\System.Graphics.SharpDX.Shared.projitems*{5163bcb2-4d70-42da-975a-af55d6b6a0b3}*SharedItemsImports = 13
@ -67,6 +69,12 @@ Global
{BD41610F-2F5B-40BA-AAC4-5F7EEBDC462C}.Release|Any CPU.Build.0 = Release|Any CPU
{BD41610F-2F5B-40BA-AAC4-5F7EEBDC462C}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{BD41610F-2F5B-40BA-AAC4-5F7EEBDC462C}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.Release|Any CPU.Build.0 = Release|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072}.AppStore|Any CPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -77,6 +85,7 @@ Global
{C7613109-6198-402E-953F-57EA81E8238E} = {9E4B772B-D417-4147-B8B1-FD9E3B0B4EC5}
{05D753E7-C4B3-4DA7-97E0-66E5FF695F42} = {9E4B772B-D417-4147-B8B1-FD9E3B0B4EC5}
{BD41610F-2F5B-40BA-AAC4-5F7EEBDC462C} = {9E4B772B-D417-4147-B8B1-FD9E3B0B4EC5}
{D69CA0F0-51A5-4D8B-9C2B-69C0F1506072} = {8A2197EB-6E30-495D-9DE9-2E40032FB2E9}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0B07E734-6AE2-4A12-AD60-C072F3695854}

Просмотреть файл

@ -1,27 +1,34 @@
using System.Diagnostics;
using System.Globalization;
namespace System.Graphics
{
public class Color
[DebuggerDisplay("Red={Red}, Green={Green}, Blue={Blue}, Alpha={Alpha}")]
public class Color
{
public readonly float Red;
public readonly float Green;
public readonly float Blue;
public readonly float Alpha = 1;
public Color(float gray)
{
Red = Green = Blue = gray.Clamp(0,1);
}
public Color(float red, float green, float blue)
{
Red = red;
Green = green;
Blue = blue;
Red = red.Clamp(0, 1);
Green = green.Clamp(0, 1);
Blue = blue.Clamp(0, 1);
}
public Color(float red, float green, float blue, float alpha)
{
Red = red;
Green = green;
Blue = blue;
Alpha = alpha;
Red = red.Clamp(0,1);
Green = green.Clamp(0,1);
Blue = blue.Clamp(0,1);
Alpha = alpha.Clamp(0,1);
}
public Color(string colorAsHex)
@ -72,19 +79,37 @@ namespace System.Graphics
Alpha = alpha / 255f;
}
public static Color FromBytes(byte red, byte green, byte blue) => Color.FromBytes(red, green, blue, 255);
public static Color FromBytes(byte red, byte green, byte blue, byte alpha)
=> new Color(red / 255f, green / 255f, blue / 255f, alpha / 255f);
public override string ToString()
{
return $"[Color: Red={Red}, Green={Green}, Blue={Blue}, Alpha={Alpha}]";
}
public override int GetHashCode()
{
return ((int)Red ^ (int)Blue) ^ ((int)Green ^ (int)Alpha);
unchecked
{
int hashcode = Red.GetHashCode();
hashcode = (hashcode * 397) ^ Green.GetHashCode();
hashcode = (hashcode * 397) ^ Blue.GetHashCode();
hashcode = (hashcode * 397) ^ Alpha.GetHashCode();
return hashcode;
}
}
public string ToHexString()
public override bool Equals(object obj)
{
return "#" + ToHexString(Red) + ToHexString(Green) + ToHexString(Blue);
if (obj is Color other)
return Red == other.Red && Green == other.Green && Blue == other.Blue && Alpha == other.Alpha;
return base.Equals(obj);
}
public string ToHex(bool includeAlpha = false)
{
if (includeAlpha || Alpha < 1)
return "#" + ToHex(Red) + ToHex(Green) + ToHex(Blue) + ToHex(Alpha);
return "#" + ToHex(Red) + ToHex(Green) + ToHex(Blue);
}
public Paint AsPaint()
@ -108,21 +133,13 @@ namespace System.Graphics
{
return new Color(Red,Green,Blue, Alpha * multiplyBy);
}
public string ToHexStringIncludingAlpha()
{
if (Alpha < 1)
return ToHexString() + ToHexString(Alpha);
return ToHexString();
public static string ToHex(float r, float g, float b)
{
return "#" + ToHex(r) + ToHex(g) + ToHex(b);
}
public static string ToHexString(float r, float g, float b)
{
return "#" + ToHexString(r) + ToHexString(g) + ToHexString(b);
}
private static string ToHexString(float value)
private static string ToHex(float value)
{
var intValue = (int)(255f * value);
var stringValue = intValue.ToString("X");
@ -132,13 +149,6 @@ namespace System.Graphics
return stringValue;
}
public static Color FromHsla(float h, float s, float l, float a = 1)
{
float red, green, blue;
ConvertToRgb(h, s, l, out red, out green, out blue);
return new Color(red, green, blue);
}
public float GetLuminosity()
{
float v = Math.Max(Red, Green);
@ -155,9 +165,45 @@ namespace System.Graphics
{
ConvertToHsl(Red,Green,Blue, out var h, out var s, out var l);
l+= delta;
l = l.Clamp(0, 1);
return FromHsla(h,s,l,Alpha);
}
public Color WithLuminosity(float luminosity)
{
ConvertToHsl(Red, Green, Blue, out var h, out var s, out var l);
return FromHsla(h, s, luminosity, Alpha);
}
public float GetSaturation()
{
ConvertToHsl(Red, Green, Blue, out var h, out var s, out var l);
return s;
}
public Color WithSaturation(float saturation)
{
ConvertToHsl(Red, Green, Blue, out var h, out var s, out var l);
return FromHsla(h, saturation, l, Alpha);
}
public float GetHue()
{
ConvertToHsl(Red, Green, Blue, out var h, out var s, out var l);
return h;
}
public Color WithHue(float hue)
{
ConvertToHsl(Red, Green, Blue, out var h, out var s, out var l);
return FromHsla(hue, s, l, Alpha);
}
public static Color FromHex(string hex)
{
return new Color(hex);
}
public static Color FromHsva(float h, float s, float v, float a)
{
h = h.Clamp(0, 1);
@ -187,7 +233,32 @@ namespace System.Graphics
public static Color FromUint(uint argb)
{
return FromRgba((byte)((argb & 0x00ff0000) >> 0x10), (byte)((argb & 0x0000ff00) >> 0x8), (byte)(argb & 0x000000ff), (byte)((argb & 0xff000000) >> 0x18));
return FromRgba((byte)((argb & 0x00ff0000) >> 0x10), (byte)((argb & 0x0000ff00) >> 0x8), (byte)(argb & 0x000000ff), (double)(byte)((argb & 0xff000000) >> 0x18));
}
public static Color FromRgb(byte red, byte green, byte blue)
{
return Color.FromRgba(red, green, blue, 255);
}
public static Color FromRgba(byte red, byte green, byte blue, byte alpha)
{
return new Color(red / 255f, green / 255f, blue / 255f, alpha / 255f);
}
public static Color FromRgb(float red, float green, float blue)
{
return Color.FromRgba(red, green, blue, 1);
}
public static Color FromRgb(double red, double green, double blue)
{
return Color.FromRgba(red, green, blue, 1);
}
public static Color FromRgba(float r, float g, float b, float a)
{
return new Color(r, g, b, a);
}
public static Color FromRgba(double r, double g, double b, double a)
@ -195,6 +266,20 @@ namespace System.Graphics
return new Color((float)r, (float)g, (float)b, (float)a);
}
public static Color FromHsla(float h, float s, float l, float a = 1)
{
float red, green, blue;
ConvertToRgb(h, s, l, out red, out green, out blue);
return new Color(red, green, blue, a);
}
public static Color FromHsla(double h, double s, double l, double a = 1)
{
float red, green, blue;
ConvertToRgb((float)h, (float)s, (float)l, out red, out green, out blue);
return new Color(red, green, blue, (float)a);
}
public static Color FromHsv(float h, float s, float v)
{
return FromHsva(h, s, v, 1f);

Просмотреть файл

@ -1256,7 +1256,7 @@ namespace System.Graphics.CoreGraphics
context.TextMatrix = CGAffineTransform.MakeIdentity();
context.TextMatrix.Translate(ix, iy);
var attributedString = text.AsNSAttributedString(fontName, fontSize, fontColor?.ToHexString(), true);
var attributedString = text.AsNSAttributedString(fontName, fontSize, fontColor?.ToHex(), true);
if (attributedString == null)
return;

Просмотреть файл

@ -0,0 +1,298 @@
using System;
using System.Collections.Generic;
using System.Graphics;
using Xunit;
namespace Xamarin.Forms.Core.UnitTests
{
public class ColorUnitTests
{
[Fact]
public void TestHSLPostSetEquality()
{
var color = new Color(1, 0.5f, 0.2f);
var color2 = color;
color2 = color.WithLuminosity(.2f);
Assert.False(color == color2);
}
[Fact]
public void TestHSLPostSetInequality()
{
var color = new Color(1, 0.5f, 0.2f);
var color2 = color;
color2 = color.WithLuminosity(.2f);
Assert.True(color != color2);
}
[Fact]
public void TestHSLSetToDefaultValue()
{
var color = new Color(0.2f, 0.5f, 0.8f);
// saturation is initialized to 0, make sure we still update
color = color.WithSaturation(0);
Assert.Equal(color.Red, color.Green);
Assert.Equal(color.Red, color.Blue);
}
[Fact]
public void TestHSLModifiers()
{
var color = Color.FromHsla(.8f, .6f, .2f);
Assert.Equal(Color.FromHsla(.1f, .6f, .2f), color.WithHue(.1f));
Assert.Equal(Color.FromHsla(.8f, .1f, .2f), color.WithSaturation(.1f));
Assert.Equal(Color.FromHsla(.8f, .6f, .1f), color.WithLuminosity(.1f));
}
[Fact]
public void TestMultiplyAlpha()
{
var color = new Color(1, 1, 1, 1);
color = color.MultiplyAlpha(0.25f);
Assert.Equal(.25, color.Alpha);
color = Color.FromHsla(1, 1, 1, 1);
color = color.MultiplyAlpha(0.25f);
Assert.Equal(.25, color.Alpha);
}
[Fact]
public void TestClamping()
{
var color = new Color(2, 2, 2, 2);
Assert.Equal(1, color.Red);
Assert.Equal(1, color.Green);
Assert.Equal(1, color.Blue);
Assert.Equal(1, color.Alpha);
color = new Color(-1, -1, -1, -1);
Assert.Equal(0, color.Red);
Assert.Equal(0, color.Green);
Assert.Equal(0, color.Blue);
Assert.Equal(0, color.Alpha);
}
[Fact]
public void TestRGBToHSL()
{
var color = new Color(.5f, .1f, .1f);
Assert.Equal(1, color.GetHue(), 3);
Assert.Equal(0.662, color.GetSaturation(), 1);
Assert.Equal(0.302, color.GetLuminosity(), 1);
}
[Fact]
public void TestHSLToRGB()
{
var color = Color.FromHsla(0, .662, .302);
Assert.Equal(0.5, color.Red, 2);
Assert.Equal(0.1, color.Green, 2);
Assert.Equal(0.1, color.Blue, 2);
}
[Fact]
public void TestColorFromValue()
{
var color = new Color(0.2f);
Assert.Equal(new Color(0.2f, 0.2f, 0.2f, 1), color);
}
[Fact]
public void TestAddLuminosity()
{
var color = new Color(0.2f);
var brighter = color.AddLuminosity(0.2f);
Assert.Equal(brighter.GetLuminosity(), color.GetLuminosity() + 0.2,3);
}
[Fact]
public void TestZeroLuminosity()
{
var color = new Color(0.1f, 0.2f, 0.3f);
color = color.AddLuminosity(-1);
Assert.Equal(0, color.GetLuminosity());
Assert.Equal(0, color.Red);
Assert.Equal(0, color.Green);
Assert.Equal(0, color.Blue);
}
[Fact]
public void TestHashCode()
{
var color1 = new Color(0.1f);
var color2 = new Color(0.1f);
Assert.True(color1.GetHashCode() == color2.GetHashCode());
}
[Fact]
public void TestHashCodeNamedColors()
{
Color red = Colors.Red; //R=1, G=0, B=0, A=1
int hashRed = red.GetHashCode();
Color blue = Colors.Blue; //R=0, G=0, B=1, A=1
int hashBlue = blue.GetHashCode();
Assert.False(hashRed == hashBlue);
}
[Fact]
public void TestHashCodeAll()
{
Dictionary<int, Color> colorsAndHashes = new Dictionary<int, Color>();
colorsAndHashes.Add(Colors.Transparent.GetHashCode(), Colors.Transparent);
colorsAndHashes.Add(Colors.Aqua.GetHashCode(), Colors.Aqua);
colorsAndHashes.Add(Colors.Black.GetHashCode(), Colors.Black);
colorsAndHashes.Add(Colors.Blue.GetHashCode(), Colors.Blue);
colorsAndHashes.Add(Colors.Fuchsia.GetHashCode(), Colors.Fuchsia);
colorsAndHashes.Add(Colors.Gray.GetHashCode(), Colors.Gray);
colorsAndHashes.Add(Colors.Green.GetHashCode(), Colors.Green);
colorsAndHashes.Add(Colors.Lime.GetHashCode(), Colors.Lime);
colorsAndHashes.Add(Colors.Maroon.GetHashCode(), Colors.Maroon);
colorsAndHashes.Add(Colors.Navy.GetHashCode(), Colors.Navy);
colorsAndHashes.Add(Colors.Olive.GetHashCode(), Colors.Olive);
colorsAndHashes.Add(Colors.Purple.GetHashCode(), Colors.Purple);
colorsAndHashes.Add(Colors.Pink.GetHashCode(), Colors.Pink);
colorsAndHashes.Add(Colors.Red.GetHashCode(), Colors.Red);
colorsAndHashes.Add(Colors.Silver.GetHashCode(), Colors.Silver);
colorsAndHashes.Add(Colors.Teal.GetHashCode(), Colors.Teal);
colorsAndHashes.Add(Colors.Yellow.GetHashCode(), Colors.Yellow);
}
[Fact]
public void TestSetHue()
{
var color = new Color(0.2f, 0.5f, 0.7f);
color = Color.FromHsla(.2f, color.GetSaturation(), color.GetLuminosity());
Assert.Equal(0.6f, color.Red, 3);
Assert.Equal(0.7f, color.Green, 3);
Assert.Equal(0.2f, color.Blue, 3);
}
[Fact]
public void ZeroLuminToRGB()
{
var color = new Color(0);
Assert.Equal(0, color.GetLuminosity());
Assert.Equal(0, color.GetHue());
Assert.Equal(0, color.GetSaturation());
}
[Fact]
public void TestToString()
{
var color = new Color(1, 1, 1, 0.5f);
Assert.Equal("[Color: Red=1, Green=1, Blue=1, Alpha=0.5]", color.ToString());
}
[Fact]
public void TestFromHex()
{
var color = Color.FromRgb(138, 43, 226);
Assert.Equal(color, new Color("8a2be2"));
Assert.Equal(Color.FromRgba(138, 43, 226, 128), new Color("#8a2be280"));
Assert.Equal(Color.FromHex("#aabbcc"), new Color("#abc"));
Assert.Equal(Color.FromHex("#aabbccdd"), new Color("#abcd"));
}
[Fact]
public void TestToHex()
{
var colorRgb = Color.FromRgb(138, 43, 226);
Assert.Equal(Color.FromHex(colorRgb.ToHex()), colorRgb);
var colorRgba = Color.FromRgba(138, 43, 226, .2);
Assert.Equal(Color.FromHex(colorRgba.ToHex()), colorRgba);
var colorHsl = Color.FromHsla(240, 1, 1);
Assert.Equal(Color.FromHex(colorHsl.ToHex()), colorHsl);
var colorHsla = Color.FromHsla(240, 1, 1, .1f);
var hexFromHsla = new Color(colorHsla.ToHex());
Assert.Equal(hexFromHsla.Alpha, colorHsla.Alpha,2);
Assert.Equal(hexFromHsla.Red, colorHsla.Red,3);
Assert.Equal(hexFromHsla.Green, colorHsla.Green,3);
Assert.Equal(hexFromHsla.Blue, colorHsla.Blue,3);
}
[Fact]
public void TestFromHsv()
{
var color = Color.FromRgb(1, .29f, .752f);
var colorHsv = Color.FromHsv(321, 71, 100);
Assert.Equal(color.Red, colorHsv.Red,3);
Assert.Equal(color.Green, colorHsv.Green,3);
Assert.Equal(color.Blue, colorHsv.Blue,3);
}
[Fact]
public void TestFromHsva()
{
var color = Color.FromRgba(1, .29, .752, .5);
var colorHsv = Color.FromHsva(321, 71, 100, 50);
Assert.Equal(color.Red, colorHsv.Red, 3);
Assert.Equal(color.Green, colorHsv.Green,3);
Assert.Equal(color.Blue, colorHsv.Blue,3);
Assert.Equal(color.Alpha, colorHsv.Alpha,3);
}
[Fact]
public void TestFromHsvDouble()
{
var color = Color.FromRgb(1, .29f, .758f);
var colorHsv = Color.FromHsv(.89f, .71f, 1);
Assert.Equal(color.Red, colorHsv.Red,2);
Assert.Equal(color.Green, colorHsv.Green,2);
Assert.Equal(color.Blue, colorHsv.Blue,2);
}
[Fact]
public void TestFromHsvaDouble()
{
var color = Color.FromRgba(1, .29, .758, .5);
var colorHsv = Color.FromHsva(.89f, .71f, 1f, .5f);
Assert.Equal(color.Red, colorHsv.Red,2);
Assert.Equal(color.Green, colorHsv.Green,2);
Assert.Equal(color.Blue, colorHsv.Blue,2);
Assert.Equal(color.Alpha, colorHsv.Alpha,2);
}
[Fact]
public void FromRGBDouble()
{
var color = Color.FromRgb(0.2, 0.3, 0.4);
Assert.Equal(new Color(0.2f, 0.3f, 0.4f), color);
}
[Fact]
public void FromRGBADouble()
{
var color = Color.FromRgba(0.2, 0.3, 0.4, 0.5);
Assert.Equal(new Color(0.2f, 0.3f, 0.4f, 0.5f), color);
}
[Fact]
public void DefaultColorsMatch()
{
//This spot-checks a few of the fields in Color
Assert.Equal(Colors.CornflowerBlue, Color.FromRgb(100, 149, 237));
Assert.Equal(Colors.DarkSalmon, Color.FromRgb(233, 150, 122));
Assert.Equal(Colors.Transparent, Color.FromRgba(0, 0, 0, 0));
Assert.Equal(Colors.Wheat, Color.FromRgb(245, 222, 179));
Assert.Equal(Colors.White, Color.FromRgb(255, 255, 255));
}
}
}

Просмотреть файл

@ -0,0 +1,25 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.3">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="coverlet.collector" Version="1.3.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\System.Graphics\System.Graphics.csproj" />
</ItemGroup>
</Project>