using System; namespace Prism.UnitTests { public class PremultipliedLinearColorTests : UnitTestSharp.TestFixture { private const double Tolerance = 1e-9; public static bool Near(double expected, double actual) { return Math.Abs(expected - actual) < Tolerance; } public class CtorTests : UnitTestSharp.TestFixture { public void AssignsAllFourChannelsAsGiven() { var color = new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4); CheckEqual(0.1, color.Red); CheckEqual(0.2, color.Green); CheckEqual(0.3, color.Blue); CheckEqual(0.4, color.Alpha); } public void ChannelsAboveAlpha_AreKept() { var color = new PremultipliedLinearColor(1, 1, 1, 0); CheckEqual(1.0, color.Red); CheckEqual(0.0, color.Alpha); } public void NaNChannel_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new PremultipliedLinearColor(0, double.NaN, 0, 1); } public void InfiniteChannel_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new PremultipliedLinearColor(0, 0, 0, double.PositiveInfinity); } } public class FromLinearTests : UnitTestSharp.TestFixture { public void MultipliesEachChannelByAlpha() { CheckEqual( new PremultipliedLinearColor(0.5, 0.25, 0.125, 0.5), PremultipliedLinearColor.FromLinear(new LinearSpaceColor(1, 0.5, 0.25, 0.5))); } public void AnOpaqueColor_IsUnchanged() { CheckEqual( new PremultipliedLinearColor(0.1, 0.2, 0.3, 1), PremultipliedLinearColor.FromLinear(new LinearSpaceColor(0.1, 0.2, 0.3, 1))); } public void ATransparentColor_LosesItsLight() { CheckEqual( new PremultipliedLinearColor(0, 0, 0, 0), PremultipliedLinearColor.FromLinear(new LinearSpaceColor(1, 1, 1, 0))); } } public class FromColorTests : UnitTestSharp.TestFixture { public void AnOpaqueColor_MatchesItsLinearLight() { PremultipliedLinearColor color = PremultipliedLinearColor.FromColor(Color.FromArgb(255, 0, 0)); CheckTrue(Near(1, color.Red)); CheckEqual(0.0, color.Green); CheckEqual(1.0, color.Alpha); } public void ASemiTransparentColor_ScalesItsLightByCoverage() { PremultipliedLinearColor color = PremultipliedLinearColor.FromColor(Color.FromArgb(51, 255, 255, 255)); CheckTrue(Near(0.2, color.Red)); CheckTrue(Near(0.2, color.Alpha)); } } public class ToLinearTests : UnitTestSharp.TestFixture { public void DividesEachChannelByAlpha() { CheckEqual( new LinearSpaceColor(1, 0.5, 0.25, 0.5), new PremultipliedLinearColor(0.5, 0.25, 0.125, 0.5).ToLinear()); } public void UndoesFromLinear() { var original = new LinearSpaceColor(0.5, 0.25, 0.125, 0.25); CheckEqual(original, PremultipliedLinearColor.FromLinear(original).ToLinear()); } public void ZeroAlpha_GivesTransparentBlack() { CheckEqual( new LinearSpaceColor(0, 0, 0, 0), new PremultipliedLinearColor(1, 1, 1, 0).ToLinear()); } } public class ToColorTests : UnitTestSharp.TestFixture { public void UndoesFromColor() { Color original = Color.FromArgb(77, 12, 34, 56); CheckEqual(original, PremultipliedLinearColor.FromColor(original).ToColor()); } public void ALightBrighterThanWhite_ClampsToFullChannel() { CheckEqual(Color.FromArgb(255, 255, 0, 0), new PremultipliedLinearColor(2, 0, 0, 1).ToColor()); } public void ZeroAlpha_GivesTransparentBlack() { CheckEqual(Color.FromArgb(0, 0, 0, 0), new PremultipliedLinearColor(1, 1, 1, 0).ToColor()); } } public class LerpTests : UnitTestSharp.TestFixture { public void AtZero_IsTheStart() { var from = new PremultipliedLinearColor(0.25, 0.5, 0.125, 0.75); CheckEqual(from, PremultipliedLinearColor.Lerp(from, new PremultipliedLinearColor(1, 1, 1, 1), 0)); } public void AtOne_IsTheEnd() { var to = new PremultipliedLinearColor(0.25, 0.5, 0.125, 0.75); CheckEqual(to, PremultipliedLinearColor.Lerp(new PremultipliedLinearColor(1, 1, 1, 1), to, 1)); } public void BlendsEveryChannelLinearly() { CheckEqual( new PremultipliedLinearColor(0.5, 0.25, 0.125, 0.5), PremultipliedLinearColor.Lerp( new PremultipliedLinearColor(0, 0, 0, 0), new PremultipliedLinearColor(1, 0.5, 0.25, 1), 0.5)); } public void MatchesTheAlphaAwareBlendOfTheStraightColors() { var from = new LinearSpaceColor(0.5, 0.25, 0.125, 0.25); var to = new LinearSpaceColor(1, 0.5, 0.25, 0.75); CheckEqual( PremultipliedLinearColor.FromLinear(LinearSpaceColor.Lerp(from, to, 0.5)), PremultipliedLinearColor.Lerp( PremultipliedLinearColor.FromLinear(from), PremultipliedLinearColor.FromLinear(to), 0.5)); } public void AmountBelowZero_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); PremultipliedLinearColor.Lerp(default, default, -0.1); } public void AmountAboveOne_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); PremultipliedLinearColor.Lerp(default, default, 1.1); } public void NaNAmount_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); PremultipliedLinearColor.Lerp(default, default, double.NaN); } } public class AddTests : UnitTestSharp.TestFixture { public void SumsEveryChannel() { CheckEqual( new PremultipliedLinearColor(0.5, 0.75, 0.25, 0.75), PremultipliedLinearColor.Add( new PremultipliedLinearColor(0.25, 0.5, 0.125, 0.5), new PremultipliedLinearColor(0.25, 0.25, 0.125, 0.25))); } public void ChannelsMayPassOne() { CheckEqual( 1.5, PremultipliedLinearColor.Add( new PremultipliedLinearColor(1, 0, 0, 1), new PremultipliedLinearColor(0.5, 0, 0, 0)).Red); } } public class OverTests : UnitTestSharp.TestFixture { public void HalfCoveringForeground_ShowsHalfTheBackground() { CheckEqual( new PremultipliedLinearColor(0.5, 0.125, 0.125, 1), PremultipliedLinearColor.Over( new PremultipliedLinearColor(0.5, 0, 0, 0.5), new PremultipliedLinearColor(0, 0.25, 0.25, 1))); } public void AnOpaqueForeground_HidesTheBackground() { var foreground = new PremultipliedLinearColor(0.5, 0.25, 0.125, 1); CheckEqual( foreground, PremultipliedLinearColor.Over(foreground, new PremultipliedLinearColor(1, 1, 1, 1))); } public void ATransparentForeground_LeavesTheBackground() { var background = new PremultipliedLinearColor(0.5, 0.25, 0.125, 0.5); CheckEqual( background, PremultipliedLinearColor.Over(new PremultipliedLinearColor(0, 0, 0, 0), background)); } public void AZeroAlphaForeground_BrightensTheBackground() { CheckEqual( new PremultipliedLinearColor(1.5, 1.5, 1.5, 1), PremultipliedLinearColor.Over( new PremultipliedLinearColor(1, 1, 1, 0), new PremultipliedLinearColor(0.5, 0.5, 0.5, 1))); } public void IsNotCommutative() { var first = new PremultipliedLinearColor(0.5, 0, 0, 0.5); var second = new PremultipliedLinearColor(0, 0.5, 0, 0.5); CheckFalse( PremultipliedLinearColor.Over(first, second) == PremultipliedLinearColor.Over(second, first)); } } public class EqualityTests : UnitTestSharp.TestFixture { public void SameChannels_AreEqual() { var first = new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4); var second = new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4); CheckTrue(first.Equals(second)); CheckTrue(first == second); CheckFalse(first != second); } public void AnyDifferentChannel_IsNotEqual() { var baseColor = new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4); CheckFalse(baseColor.Equals(new PremultipliedLinearColor(0.9, 0.2, 0.3, 0.4))); CheckFalse(baseColor.Equals(new PremultipliedLinearColor(0.1, 0.9, 0.3, 0.4))); CheckFalse(baseColor.Equals(new PremultipliedLinearColor(0.1, 0.2, 0.9, 0.4))); CheckFalse(baseColor.Equals(new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.9))); CheckTrue(baseColor != new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.9)); } public void BoxedColor_IsEqualToTheSameColor() { CheckTrue(new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4).Equals( (object)new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4))); } public void ANonColor_IsNotEqual() { CheckFalse(new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4).Equals("color")); } public void EqualColors_HaveTheSameHashCode() { CheckEqual( new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4).GetHashCode(), new PremultipliedLinearColor(0.1, 0.2, 0.3, 0.4).GetHashCode()); } } } }