From a2b5b3ad3b035692d81ec1645372cefbc2ea1426 Mon Sep 17 00:00:00 2001 From: Rustam Sayfutdinov Date: Wed, 10 Jun 2020 10:19:47 +0300 Subject: [PATCH] Fix machine epsilon for double elsewhere --- src/Avalonia.Base/Properties/AssemblyInfo.cs | 3 +- src/Avalonia.Base/Utilities/MathUtilities.cs | 2 +- src/Avalonia.Controls/Grid.cs | 35 ++++--------------- src/Avalonia.Controls/Slider.cs | 2 +- .../Utils/BorderRenderHelper.cs | 3 +- src/Avalonia.Visuals/Media/DrawingContext.cs | 5 +-- .../Media/TextFormatting/TextLayout.cs | 3 +- .../Media/DrawingContextImpl.cs | 2 +- 8 files changed, 19 insertions(+), 36 deletions(-) diff --git a/src/Avalonia.Base/Properties/AssemblyInfo.cs b/src/Avalonia.Base/Properties/AssemblyInfo.cs index 75d58f45d5..fd5e411850 100644 --- a/src/Avalonia.Base/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Base/Properties/AssemblyInfo.cs @@ -7,4 +7,5 @@ using Avalonia.Metadata; [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data.Converters")] [assembly: InternalsVisibleTo("Avalonia.Base.UnitTests")] [assembly: InternalsVisibleTo("Avalonia.UnitTests")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] +[assembly: InternalsVisibleTo("Avalonia.Controls")] diff --git a/src/Avalonia.Base/Utilities/MathUtilities.cs b/src/Avalonia.Base/Utilities/MathUtilities.cs index 3fb5f7a162..6da695407b 100644 --- a/src/Avalonia.Base/Utilities/MathUtilities.cs +++ b/src/Avalonia.Base/Utilities/MathUtilities.cs @@ -9,7 +9,7 @@ namespace Avalonia.Utilities public static class MathUtilities { // smallest such that 1.0+DoubleEpsilon != 1.0 - private const double DoubleEpsilon = 2.2204460492503131e-016; + internal static readonly double DoubleEpsilon = 2.2204460492503131e-016; /// /// AreClose - Returns whether or not two doubles are "close". That is, whether or diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs index 1781067abb..e10d78917e 100644 --- a/src/Avalonia.Controls/Grid.cs +++ b/src/Avalonia.Controls/Grid.cs @@ -1228,7 +1228,7 @@ namespace Avalonia.Controls Debug.Assert(1 < count && 0 <= start && (start + count) <= definitions.Count); // avoid processing when asked to distribute "0" - if (!_IsZero(requestedSize)) + if (!MathUtilities.IsZero(requestedSize)) { DefinitionBase[] tempDefinitions = TempDefinitions; // temp array used to remember definitions for sorting int end = start + count; @@ -1306,7 +1306,7 @@ namespace Avalonia.Controls } // sanity check: requested size must all be distributed - Debug.Assert(_IsZero(sizeToDistribute)); + Debug.Assert(MathUtilities.IsZero(sizeToDistribute)); } else if (requestedSize <= rangeMaxSize) { @@ -1346,7 +1346,7 @@ namespace Avalonia.Controls } // sanity check: requested size must all be distributed - Debug.Assert(_IsZero(sizeToDistribute)); + Debug.Assert(MathUtilities.IsZero(sizeToDistribute)); } else { @@ -1358,7 +1358,7 @@ namespace Avalonia.Controls double equalSize = requestedSize / count; if (equalSize < maxMaxSize - && !_AreClose(equalSize, maxMaxSize)) + && !MathUtilities.AreClose(equalSize, maxMaxSize)) { // equi-size is less than maximum of maxSizes. // in this case distribute so that smaller definitions grow faster than @@ -2151,7 +2151,7 @@ namespace Avalonia.Controls // and precision of floating-point computation. (However, the resulting // display is subject to anti-aliasing problems. TANSTAAFL.) - if (!_AreClose(roundedTakenSize, finalSize)) + if (!MathUtilities.AreClose(roundedTakenSize, finalSize)) { // Compute deltas for (int i = 0; i < definitions.Count; ++i) @@ -2168,7 +2168,7 @@ namespace Avalonia.Controls if (roundedTakenSize > finalSize) { int i = definitions.Count - 1; - while ((adjustedSize > finalSize && !_AreClose(adjustedSize, finalSize)) && i >= 0) + while ((adjustedSize > finalSize && !MathUtilities.AreClose(adjustedSize, finalSize)) && i >= 0) { DefinitionBase definition = definitions[definitionIndices[i]]; double final = definition.SizeCache - dpiIncrement; @@ -2184,7 +2184,7 @@ namespace Avalonia.Controls else if (roundedTakenSize < finalSize) { int i = 0; - while ((adjustedSize < finalSize && !_AreClose(adjustedSize, finalSize)) && i < definitions.Count) + while ((adjustedSize < finalSize && !MathUtilities.AreClose(adjustedSize, finalSize)) && i < definitions.Count) { DefinitionBase definition = definitions[definitionIndices[i]]; double final = definition.SizeCache + dpiIncrement; @@ -2595,27 +2595,6 @@ namespace Avalonia.Controls set { SetFlags(value, Flags.HasGroup3CellsInAutoRows); } } - /// - /// fp version of d == 0. - /// - /// Value to check. - /// true if d == 0. - private static bool _IsZero(double d) - { - return (Math.Abs(d) < double.Epsilon); - } - - /// - /// fp version of d1 == d2 - /// - /// First value to compare - /// Second value to compare - /// true if d1 == d2 - private static bool _AreClose(double d1, double d2) - { - return (Math.Abs(d1 - d2) < double.Epsilon); - } - /// /// Returns reference to extended data bag. /// diff --git a/src/Avalonia.Controls/Slider.cs b/src/Avalonia.Controls/Slider.cs index ec23bfa396..6cebe32322 100644 --- a/src/Avalonia.Controls/Slider.cs +++ b/src/Avalonia.Controls/Slider.cs @@ -193,7 +193,7 @@ namespace Avalonia.Controls var orient = Orientation == Orientation.Horizontal; var pointDen = orient ? _track.Bounds.Width : _track.Bounds.Height; - pointDen += double.Epsilon; // Just add epsilon to avoid divide by zero exceptions. + pointDen += MathUtilities.DoubleEpsilon; // Just add epsilon to avoid divide by zero exceptions. var pointNum = orient ? x.Position.X : x.Position.Y; var logicalPos = MathUtilities.Clamp(pointNum / pointDen, 0.0d, 1.0d); diff --git a/src/Avalonia.Controls/Utils/BorderRenderHelper.cs b/src/Avalonia.Controls/Utils/BorderRenderHelper.cs index 51eb6edbea..438cbc8b27 100644 --- a/src/Avalonia.Controls/Utils/BorderRenderHelper.cs +++ b/src/Avalonia.Controls/Utils/BorderRenderHelper.cs @@ -1,6 +1,7 @@ using System; using Avalonia.Media; using Avalonia.Platform; +using Avalonia.Utilities; namespace Avalonia.Controls.Utils { @@ -119,7 +120,7 @@ namespace Avalonia.Controls.Utils } var rect = new Rect(_size); - if (Math.Abs(borderThickness) > double.Epsilon) + if (!MathUtilities.IsZero(borderThickness)) rect = rect.Deflate(borderThickness * 0.5); var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight, _cornerRadius.BottomRight, _cornerRadius.BottomLeft); diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs index 6fdcd9631b..b1cf1aecc9 100644 --- a/src/Avalonia.Visuals/Media/DrawingContext.cs +++ b/src/Avalonia.Visuals/Media/DrawingContext.cs @@ -4,6 +4,7 @@ using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Rendering.SceneGraph; using Avalonia.Threading; +using Avalonia.Utilities; using Avalonia.Visuals.Media.Imaging; namespace Avalonia.Media @@ -154,12 +155,12 @@ namespace Avalonia.Media return; } - if (Math.Abs(radiusX) > double.Epsilon) + if (!MathUtilities.IsZero(radiusX)) { radiusX = Math.Min(radiusX, rect.Width / 2); } - if (Math.Abs(radiusY) > double.Epsilon) + if (!MathUtilities.IsZero(radiusY)) { radiusY = Math.Min(radiusY, rect.Height / 2); } diff --git a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs index 720185a3ad..0292398782 100644 --- a/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs +++ b/src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs @@ -4,6 +4,7 @@ using System.Linq; using Avalonia.Media.Immutable; using Avalonia.Media.TextFormatting.Unicode; using Avalonia.Platform; +using Avalonia.Utilities; using Avalonia.Utility; namespace Avalonia.Media.TextFormatting @@ -184,7 +185,7 @@ namespace Avalonia.Media.TextFormatting /// private void UpdateLayout() { - if (_text.IsEmpty || Math.Abs(MaxWidth) < double.Epsilon || Math.Abs(MaxHeight) < double.Epsilon) + if (_text.IsEmpty || MathUtilities.IsZero(MaxWidth) || MathUtilities.IsZero(MaxHeight)) { var textLine = CreateEmptyTextLine(0); diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index bbb45cf64c..9b7ba4844a 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -236,7 +236,7 @@ namespace Avalonia.Direct2D1.Media Math.Max(rrect.RadiiTopRight.X, Math.Max(rrect.RadiiBottomRight.X, rrect.RadiiBottomLeft.X))); var radiusY = Math.Max(rrect.RadiiTopLeft.Y, Math.Max(rrect.RadiiTopRight.Y, Math.Max(rrect.RadiiBottomRight.Y, rrect.RadiiBottomLeft.Y))); - var isRounded = Math.Abs(radiusX) > double.Epsilon || Math.Abs(radiusY) > double.Epsilon; + var isRounded = !MathUtilities.IsZero(radiusX) || !MathUtilities.IsZero(radiusY); if (brush != null) {