From a6cfe88c61bf971ce20fc6c9dabde5b3553a049e Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Tue, 8 Jun 2021 23:40:40 +0200 Subject: [PATCH 1/6] Change ImmutableSolidColorBrush to a class. --- .../Media/Immutable/ImmutableSolidColorBrush.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs index 010184ad3b..8e93ac580e 100644 --- a/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs @@ -5,7 +5,7 @@ namespace Avalonia.Media.Immutable /// /// Fills an area with a solid color. /// - public readonly struct ImmutableSolidColorBrush : ISolidColorBrush, IEquatable + public class ImmutableSolidColorBrush : ISolidColorBrush, IEquatable { /// /// Initializes a new instance of the class. @@ -48,8 +48,9 @@ namespace Avalonia.Media.Immutable public bool Equals(ImmutableSolidColorBrush other) { - // ReSharper disable once CompareOfFloatsByEqualityOperator - return Color == other.Color && Opacity == other.Opacity; + if (ReferenceEquals(null, other)) return false; + if (ReferenceEquals(this, other)) return true; + return Color.Equals(other.Color) && Opacity.Equals(other.Opacity); } public override bool Equals(object obj) @@ -67,12 +68,12 @@ namespace Avalonia.Media.Immutable public static bool operator ==(ImmutableSolidColorBrush left, ImmutableSolidColorBrush right) { - return left.Equals(right); + return Equals(left, right); } public static bool operator !=(ImmutableSolidColorBrush left, ImmutableSolidColorBrush right) { - return !left.Equals(right); + return !Equals(left, right); } /// From f9103e2c9561b614b3c94a71839c80f0ae8d4416 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Tue, 8 Jun 2021 23:41:13 +0200 Subject: [PATCH 2/6] Parse brushes as immutable by default. --- src/Avalonia.Visuals/Media/Brush.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/Media/Brush.cs b/src/Avalonia.Visuals/Media/Brush.cs index fb03d19a4e..cf7f5f531c 100644 --- a/src/Avalonia.Visuals/Media/Brush.cs +++ b/src/Avalonia.Visuals/Media/Brush.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using Avalonia.Animation; using Avalonia.Animation.Animators; +using Avalonia.Media.Immutable; namespace Avalonia.Media { @@ -47,7 +48,7 @@ namespace Avalonia.Media if (s[0] == '#') { - return new SolidColorBrush(Color.Parse(s)); + return new ImmutableSolidColorBrush(Color.Parse(s)); } var brush = KnownColors.GetKnownBrush(s); From e742f81a7d2b1722d301132ce452a127a70e7af5 Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Tue, 8 Jun 2021 23:41:34 +0200 Subject: [PATCH 3/6] Parse brushes during compile time. --- .../AvaloniaXamlIlLanguageParseIntrinsics.cs | 14 ++++++++++++++ .../Transformers/AvaloniaXamlIlWellKnownTypes.cs | 9 ++++++++- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs index 059b5650cb..4592b9c8b4 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/AvaloniaXamlIlLanguageParseIntrinsics.cs @@ -207,6 +207,20 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions return true; } + if (types.IBrush.IsAssignableFrom(type)) + { + if (Color.TryParse(text, out Color color)) + { + var brushTypeRef = new XamlAstClrTypeReference(node, types.ImmutableSolidColorBrush, false); + + result = new XamlAstNewClrObjectNode(node, brushTypeRef, + types.ImmutableSolidColorBrushConstructorColor, + new List { new XamlConstantNode(node, types.UInt, color.ToUint32()) }); + + return true; + } + } + result = null; return false; } diff --git a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs index c4995b2de3..6dd3521183 100644 --- a/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs +++ b/src/Markup/Avalonia.Markup.Xaml.Loader/CompilerExtensions/Transformers/AvaloniaXamlIlWellKnownTypes.cs @@ -80,7 +80,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers public IXamlType ColumnDefinitions { get; } public IXamlType Classes { get; } public IXamlMethod ClassesBindMethod { get; } - public IXamlProperty StyledElementClassesProperty { get; set; } + public IXamlProperty StyledElementClassesProperty { get; } + public IXamlType IBrush { get; } + public IXamlType ImmutableSolidColorBrush { get; } + public IXamlConstructor ImmutableSolidColorBrushConstructorColor { get; } public AvaloniaXamlIlWellKnownTypes(TransformerConfiguration cfg) { @@ -178,6 +181,10 @@ namespace Avalonia.Markup.Xaml.XamlIl.CompilerExtensions.Transformers .FindMethod( "BindClass", IDisposable, false, IStyledElement, cfg.WellKnownTypes.String, IBinding, cfg.WellKnownTypes.Object); + + IBrush = cfg.TypeSystem.GetType("Avalonia.Media.IBrush"); + ImmutableSolidColorBrush = cfg.TypeSystem.GetType("Avalonia.Media.Immutable.ImmutableSolidColorBrush"); + ImmutableSolidColorBrushConstructorColor = ImmutableSolidColorBrush.GetConstructor(new List { UInt }); } } From 17d9755c3f22f3a20b09996fc7d72e2ffd3f406e Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Sat, 10 Jul 2021 21:43:19 +0200 Subject: [PATCH 4/6] Update API compat. --- src/Avalonia.Visuals/ApiCompatBaseline.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Avalonia.Visuals/ApiCompatBaseline.txt b/src/Avalonia.Visuals/ApiCompatBaseline.txt index c917902dc3..39a4c3004c 100644 --- a/src/Avalonia.Visuals/ApiCompatBaseline.txt +++ b/src/Avalonia.Visuals/ApiCompatBaseline.txt @@ -5,6 +5,7 @@ InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Task MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract. InterfacesShouldHaveSameMembers : Interface member 'public System.Threading.Tasks.Task Avalonia.Animation.IPageTransition.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean, System.Threading.CancellationToken)' is present in the implementation but not in the contract. MembersMustExist : Member 'public System.Threading.Tasks.Task Avalonia.Animation.PageSlide.Start(Avalonia.Visual, Avalonia.Visual, System.Boolean)' does not exist in the implementation but it does exist in the contract. +TypeCannotChangeClassification : Type 'Avalonia.Media.Immutable.ImmutableSolidColorBrush' is a 'class' in the implementation but is a 'struct' in the contract. MembersMustExist : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext)' does not exist in the implementation but it does exist in the contract. CannotAddAbstractMembers : Member 'public void Avalonia.Media.TextFormatting.DrawableTextRun.Draw(Avalonia.Media.DrawingContext, Avalonia.Point)' is abstract in the implementation but is missing in the contract. CannotSealType : Type 'Avalonia.Media.TextFormatting.GenericTextParagraphProperties' is actually (has the sealed modifier) sealed in the implementation but not sealed in the contract. @@ -73,4 +74,4 @@ InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWr InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmap(System.String)' is present in the implementation but not in the contract. InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToHeight(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract. InterfacesShouldHaveSameMembers : Interface member 'public Avalonia.Platform.IWriteableBitmapImpl Avalonia.Platform.IPlatformRenderInterface.LoadWriteableBitmapToWidth(System.IO.Stream, System.Int32, Avalonia.Visuals.Media.Imaging.BitmapInterpolationMode)' is present in the implementation but not in the contract. -Total Issues: 74 +Total Issues: 75 From e55c11ec37a1fb87fe7e376c86919f69936700ea Mon Sep 17 00:00:00 2001 From: Dariusz Komosinski Date: Sat, 10 Jul 2021 21:57:53 +0200 Subject: [PATCH 5/6] Fix unit tests. --- .../StaticResourceExtensionTests.cs | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs index 0ee7384c7d..fb3fd6d7d4 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs @@ -29,7 +29,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml); var border = userControl.FindControl("border"); - var brush = (SolidColorBrush)border.Background; + var brush = (ISolidColorBrush)border.Background; Assert.Equal(0xff506070, brush.Color.ToUint32()); } @@ -72,7 +72,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml); var border = userControl.FindControl("border"); - var brush = (SolidColorBrush)border.Background; + var brush = (ISolidColorBrush)border.Background; Assert.Equal(0xff506070, brush.Color.ToUint32()); } @@ -119,7 +119,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml); var border = userControl.FindControl("border"); - var brush = (SolidColorBrush)border.Background; + var brush = (ISolidColorBrush)border.Background; Assert.Equal(0xff506070, brush.Color.ToUint32()); } @@ -149,7 +149,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var userControl = (UserControl)AvaloniaRuntimeXamlLoader.Load(xaml); var border = userControl.FindControl("border"); - var brush = (SolidColorBrush)border.Background; + var brush = (ISolidColorBrush)border.Background; Assert.Equal(0xff506070, brush.Color.ToUint32()); } @@ -200,7 +200,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions var window = (Window)AvaloniaRuntimeXamlLoader.Load(xaml); var button = window.FindControl