From 7106b37a014dbd1e52db386b35d5f7e650fd54fc Mon Sep 17 00:00:00 2001 From: workgroupengineering Date: Wed, 7 Feb 2024 10:38:15 +0100 Subject: [PATCH] fix: #14211 BoxShadow.ToString() behavior (#14228) * test: Refatctoring BoxShadowTests, handle ToString case when Blur is 0 and Spread is not zero * fix: #14211 BoxShadow.ToString() behavior --- src/Avalonia.Base/Media/BoxShadow.cs | 19 +-- src/Avalonia.Base/Media/Color.cs | 14 ++ src/Avalonia.Base/Media/KnownColors.cs | 4 + .../Media/BoxShadowTests.cs | 137 +++++++++++++----- 4 files changed, 124 insertions(+), 50 deletions(-) diff --git a/src/Avalonia.Base/Media/BoxShadow.cs b/src/Avalonia.Base/Media/BoxShadow.cs index 71a7c672f2..4b04f84938 100644 --- a/src/Avalonia.Base/Media/BoxShadow.cs +++ b/src/Avalonia.Base/Media/BoxShadow.cs @@ -2,7 +2,6 @@ using System; using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.Text; -using Avalonia.Animation.Animators; using Avalonia.Utilities; namespace Avalonia.Media @@ -90,27 +89,21 @@ namespace Avalonia.Media sb.Append("inset "); } - if (OffsetX != 0.0) - { - sb.AppendFormat("{0} ", OffsetX.ToString(CultureInfo.InvariantCulture)); - } + sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", OffsetX); - if (OffsetY != 0.0) - { - sb.AppendFormat("{0} ", OffsetY.ToString(CultureInfo.InvariantCulture)); - } + sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", OffsetY); - if (Blur != 0.0) + if (Blur != 0.0 || Spread != 0.0) { - sb.AppendFormat("{0} ", Blur.ToString(CultureInfo.InvariantCulture)); + sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", Blur); } if (Spread != 0.0) { - sb.AppendFormat("{0} ", Spread.ToString(CultureInfo.InvariantCulture)); + sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", Spread); } - sb.AppendFormat("{0}", Color.ToString()); + Color.ToString(sb); } public static unsafe BoxShadow Parse(string s) diff --git a/src/Avalonia.Base/Media/Color.cs b/src/Avalonia.Base/Media/Color.cs index d100fa2822..ba487b1e80 100644 --- a/src/Avalonia.Base/Media/Color.cs +++ b/src/Avalonia.Base/Media/Color.cs @@ -447,6 +447,20 @@ namespace Avalonia.Media return KnownColors.GetKnownColorName(rgb) ?? $"#{rgb.ToString("x8", CultureInfo.InvariantCulture)}"; } + internal void ToString(System.Text.StringBuilder builder) + { + uint rgb = ToUInt32(); + if(KnownColors.TryGetKnownColorName(rgb, out var name)) + { + builder.Append(name); + } + else + { + builder.Append('#'); + builder.AppendFormat(CultureInfo.InvariantCulture, "{0:x8}", rgb); + } + } + /// /// Returns the integer representation of the color. /// diff --git a/src/Avalonia.Base/Media/KnownColors.cs b/src/Avalonia.Base/Media/KnownColors.cs index 64cf1ef2f1..a0dea275bd 100644 --- a/src/Avalonia.Base/Media/KnownColors.cs +++ b/src/Avalonia.Base/Media/KnownColors.cs @@ -2,6 +2,7 @@ using System; using System.Reflection; using System.Collections.Generic; using Avalonia.SourceGenerator; +using System.Diagnostics.CodeAnalysis; namespace Avalonia.Media { @@ -66,6 +67,9 @@ namespace Avalonia.Media return _knownColors.TryGetValue(rgb, out var name) ? name : null; } + internal static bool TryGetKnownColorName(uint rgb, [NotNullWhen(true)] out string? name) + => _knownColors.TryGetValue(rgb, out name); + public static Color ToColor(this KnownColor color) { return Color.FromUInt32((uint)color); diff --git a/tests/Avalonia.Base.UnitTests/Media/BoxShadowTests.cs b/tests/Avalonia.Base.UnitTests/Media/BoxShadowTests.cs index c9092bb133..c553a3b953 100644 --- a/tests/Avalonia.Base.UnitTests/Media/BoxShadowTests.cs +++ b/tests/Avalonia.Base.UnitTests/Media/BoxShadowTests.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using Avalonia.Media; using Xunit; @@ -5,49 +6,111 @@ namespace Avalonia.Base.UnitTests.Media { public class BoxShadowTests { - [Fact] - public void BoxShadow_Should_Parse() + [Theory] + [MemberData(nameof(ParseGetData))] + public void BoxShadow_Should_Parse(BoxShadow expected, string source) + { + var parsered = BoxShadow.Parse(source); + Assert.Equal(expected.IsInset, parsered.IsInset); + Assert.Equal(expected.OffsetX, parsered.OffsetX); + Assert.Equal(expected.OffsetY, parsered.OffsetY); + Assert.Equal(expected.Blur, parsered.Blur); + Assert.Equal(expected.Spread, parsered.Spread); + Assert.Equal(expected.Color, parsered.Color); + } + + [Theory] + [MemberData(nameof(ToStringGetData))] + public void BoxShadows_Should_ToString(BoxShadows source, string expected) => + Assert.Equal(expected, source.ToString(), true); + + public static IEnumerable ParseGetData() { foreach (var extraSpaces in new[] { false, true }) - foreach (var inset in new[] { false, true }) - for (var componentCount = 2; componentCount < 5; componentCount++) - { - var s = (inset ? "inset " : "") + "10 20"; - double blur = 0; - double spread = 0; - if (componentCount > 2) - { - s += " 30"; - blur = 30; - } + foreach (var inset in new[] { false, true }) + foreach (var color in new[] { "red", "#FF122403" }) + for (var componentCount = 2; componentCount < 5; componentCount++) + { + var s = (inset ? "inset " : "") + "10 20"; + if (componentCount > 2) + { + s += " 30"; + } - if (componentCount > 3) - { - s += " 40"; - spread = 40; - } - - s += " red"; - - if (extraSpaces) - s = " " + s.Replace(" ", " ") + " "; - - var parsed = BoxShadow.Parse(s); - Assert.Equal(inset, parsed.IsInset); - Assert.Equal(10, parsed.OffsetX); - Assert.Equal(20, parsed.OffsetY); - Assert.Equal(blur, parsed.Blur); - Assert.Equal(spread, parsed.Spread); - Assert.Equal(Colors.Red, parsed.Color); - } + if (componentCount > 3) + { + s += " 40"; + } + + s += " " + color; + + if (extraSpaces) + s = " " + s.Replace(" ", " ") + " "; + + var parsed = BoxShadow.Parse(s); + yield return new object[] { parsed, s }; + } } - [Fact] - public void BoxShadows_Should_ToString() + public static IEnumerable ToStringGetData() { - const string source = "-20 -20 60 #CCFFFFFF, 20 20 60 #33000000"; - var parsed = BoxShadows.Parse(source); - Assert.Equal(source, parsed.ToString(), true); + yield return new object[] + { + new BoxShadows( + new BoxShadow() + { + OffsetX = -15, + OffsetY = 20, + Spread = 5, + Color = Colors.Red, + }), + "-15 20 0 5 red" + }; + yield return new object[] + { + new BoxShadows( + new BoxShadow() + { + IsInset = true, + OffsetX = -15, + OffsetY = 20, + Spread = 5, + Color = Colors.Red, + }), + "inset -15 20 0 5 red" + }; + yield return new object[] + { + new BoxShadows( + new BoxShadow() + { + OffsetX = -15, + OffsetY = 20, + Blur = 5, + Color = Colors.Red, + }), + "-15 20 5 red" + }; + yield return new object[] + { + new BoxShadows( + new BoxShadow() + { + OffsetX = -20, + OffsetY = -20, + Blur = 60, + Color = Color.Parse("#CCFFFFFF") + }, + new BoxShadow[] { new() + { + OffsetX = 20, + OffsetY = 20, + Blur = 60, + Color = Color.Parse("#33000000") + } }), + "-20 -20 60 #CCFFFFFF, 20 20 60 #33000000" + }; + } } }