Browse Source

Fix machine epsilon for double elsewhere

pull/4096/head
Rustam Sayfutdinov 6 years ago
parent
commit
a2b5b3ad3b
  1. 3
      src/Avalonia.Base/Properties/AssemblyInfo.cs
  2. 2
      src/Avalonia.Base/Utilities/MathUtilities.cs
  3. 35
      src/Avalonia.Controls/Grid.cs
  4. 2
      src/Avalonia.Controls/Slider.cs
  5. 3
      src/Avalonia.Controls/Utils/BorderRenderHelper.cs
  6. 5
      src/Avalonia.Visuals/Media/DrawingContext.cs
  7. 3
      src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs
  8. 2
      src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs

3
src/Avalonia.Base/Properties/AssemblyInfo.cs

@ -7,4 +7,5 @@ using Avalonia.Metadata;
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data.Converters")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Data.Converters")]
[assembly: InternalsVisibleTo("Avalonia.Base.UnitTests")] [assembly: InternalsVisibleTo("Avalonia.Base.UnitTests")]
[assembly: InternalsVisibleTo("Avalonia.UnitTests")] [assembly: InternalsVisibleTo("Avalonia.UnitTests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
[assembly: InternalsVisibleTo("Avalonia.Controls")]

2
src/Avalonia.Base/Utilities/MathUtilities.cs

@ -9,7 +9,7 @@ namespace Avalonia.Utilities
public static class MathUtilities public static class MathUtilities
{ {
// smallest such that 1.0+DoubleEpsilon != 1.0 // smallest such that 1.0+DoubleEpsilon != 1.0
private const double DoubleEpsilon = 2.2204460492503131e-016; internal static readonly double DoubleEpsilon = 2.2204460492503131e-016;
/// <summary> /// <summary>
/// AreClose - Returns whether or not two doubles are "close". That is, whether or /// AreClose - Returns whether or not two doubles are "close". That is, whether or

35
src/Avalonia.Controls/Grid.cs

@ -1228,7 +1228,7 @@ namespace Avalonia.Controls
Debug.Assert(1 < count && 0 <= start && (start + count) <= definitions.Count); Debug.Assert(1 < count && 0 <= start && (start + count) <= definitions.Count);
// avoid processing when asked to distribute "0" // 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 DefinitionBase[] tempDefinitions = TempDefinitions; // temp array used to remember definitions for sorting
int end = start + count; int end = start + count;
@ -1306,7 +1306,7 @@ namespace Avalonia.Controls
} }
// sanity check: requested size must all be distributed // sanity check: requested size must all be distributed
Debug.Assert(_IsZero(sizeToDistribute)); Debug.Assert(MathUtilities.IsZero(sizeToDistribute));
} }
else if (requestedSize <= rangeMaxSize) else if (requestedSize <= rangeMaxSize)
{ {
@ -1346,7 +1346,7 @@ namespace Avalonia.Controls
} }
// sanity check: requested size must all be distributed // sanity check: requested size must all be distributed
Debug.Assert(_IsZero(sizeToDistribute)); Debug.Assert(MathUtilities.IsZero(sizeToDistribute));
} }
else else
{ {
@ -1358,7 +1358,7 @@ namespace Avalonia.Controls
double equalSize = requestedSize / count; double equalSize = requestedSize / count;
if (equalSize < maxMaxSize if (equalSize < maxMaxSize
&& !_AreClose(equalSize, maxMaxSize)) && !MathUtilities.AreClose(equalSize, maxMaxSize))
{ {
// equi-size is less than maximum of maxSizes. // equi-size is less than maximum of maxSizes.
// in this case distribute so that smaller definitions grow faster than // 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 // and precision of floating-point computation. (However, the resulting
// display is subject to anti-aliasing problems. TANSTAAFL.) // display is subject to anti-aliasing problems. TANSTAAFL.)
if (!_AreClose(roundedTakenSize, finalSize)) if (!MathUtilities.AreClose(roundedTakenSize, finalSize))
{ {
// Compute deltas // Compute deltas
for (int i = 0; i < definitions.Count; ++i) for (int i = 0; i < definitions.Count; ++i)
@ -2168,7 +2168,7 @@ namespace Avalonia.Controls
if (roundedTakenSize > finalSize) if (roundedTakenSize > finalSize)
{ {
int i = definitions.Count - 1; 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]]; DefinitionBase definition = definitions[definitionIndices[i]];
double final = definition.SizeCache - dpiIncrement; double final = definition.SizeCache - dpiIncrement;
@ -2184,7 +2184,7 @@ namespace Avalonia.Controls
else if (roundedTakenSize < finalSize) else if (roundedTakenSize < finalSize)
{ {
int i = 0; 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]]; DefinitionBase definition = definitions[definitionIndices[i]];
double final = definition.SizeCache + dpiIncrement; double final = definition.SizeCache + dpiIncrement;
@ -2595,27 +2595,6 @@ namespace Avalonia.Controls
set { SetFlags(value, Flags.HasGroup3CellsInAutoRows); } set { SetFlags(value, Flags.HasGroup3CellsInAutoRows); }
} }
/// <summary>
/// fp version of <c>d == 0</c>.
/// </summary>
/// <param name="d">Value to check.</param>
/// <returns><c>true</c> if d == 0.</returns>
private static bool _IsZero(double d)
{
return (Math.Abs(d) < double.Epsilon);
}
/// <summary>
/// fp version of <c>d1 == d2</c>
/// </summary>
/// <param name="d1">First value to compare</param>
/// <param name="d2">Second value to compare</param>
/// <returns><c>true</c> if d1 == d2</returns>
private static bool _AreClose(double d1, double d2)
{
return (Math.Abs(d1 - d2) < double.Epsilon);
}
/// <summary> /// <summary>
/// Returns reference to extended data bag. /// Returns reference to extended data bag.
/// </summary> /// </summary>

2
src/Avalonia.Controls/Slider.cs

@ -193,7 +193,7 @@ namespace Avalonia.Controls
var orient = Orientation == Orientation.Horizontal; var orient = Orientation == Orientation.Horizontal;
var pointDen = orient ? _track.Bounds.Width : _track.Bounds.Height; 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 pointNum = orient ? x.Position.X : x.Position.Y;
var logicalPos = MathUtilities.Clamp(pointNum / pointDen, 0.0d, 1.0d); var logicalPos = MathUtilities.Clamp(pointNum / pointDen, 0.0d, 1.0d);

3
src/Avalonia.Controls/Utils/BorderRenderHelper.cs

@ -1,6 +1,7 @@
using System; using System;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Utilities;
namespace Avalonia.Controls.Utils namespace Avalonia.Controls.Utils
{ {
@ -119,7 +120,7 @@ namespace Avalonia.Controls.Utils
} }
var rect = new Rect(_size); var rect = new Rect(_size);
if (Math.Abs(borderThickness) > double.Epsilon) if (!MathUtilities.IsZero(borderThickness))
rect = rect.Deflate(borderThickness * 0.5); rect = rect.Deflate(borderThickness * 0.5);
var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight, var rrect = new RoundedRect(rect, _cornerRadius.TopLeft, _cornerRadius.TopRight,
_cornerRadius.BottomRight, _cornerRadius.BottomLeft); _cornerRadius.BottomRight, _cornerRadius.BottomLeft);

5
src/Avalonia.Visuals/Media/DrawingContext.cs

@ -4,6 +4,7 @@ using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Rendering.SceneGraph; using Avalonia.Rendering.SceneGraph;
using Avalonia.Threading; using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Visuals.Media.Imaging; using Avalonia.Visuals.Media.Imaging;
namespace Avalonia.Media namespace Avalonia.Media
@ -154,12 +155,12 @@ namespace Avalonia.Media
return; return;
} }
if (Math.Abs(radiusX) > double.Epsilon) if (!MathUtilities.IsZero(radiusX))
{ {
radiusX = Math.Min(radiusX, rect.Width / 2); radiusX = Math.Min(radiusX, rect.Width / 2);
} }
if (Math.Abs(radiusY) > double.Epsilon) if (!MathUtilities.IsZero(radiusY))
{ {
radiusY = Math.Min(radiusY, rect.Height / 2); radiusY = Math.Min(radiusY, rect.Height / 2);
} }

3
src/Avalonia.Visuals/Media/TextFormatting/TextLayout.cs

@ -4,6 +4,7 @@ using System.Linq;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
using Avalonia.Media.TextFormatting.Unicode; using Avalonia.Media.TextFormatting.Unicode;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Utilities;
using Avalonia.Utility; using Avalonia.Utility;
namespace Avalonia.Media.TextFormatting namespace Avalonia.Media.TextFormatting
@ -184,7 +185,7 @@ namespace Avalonia.Media.TextFormatting
/// </summary> /// </summary>
private void UpdateLayout() 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); var textLine = CreateEmptyTextLine(0);

2
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))); Math.Max(rrect.RadiiTopRight.X, Math.Max(rrect.RadiiBottomRight.X, rrect.RadiiBottomLeft.X)));
var radiusY = Math.Max(rrect.RadiiTopLeft.Y, var radiusY = Math.Max(rrect.RadiiTopLeft.Y,
Math.Max(rrect.RadiiTopRight.Y, Math.Max(rrect.RadiiBottomRight.Y, rrect.RadiiBottomLeft.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) if (brush != null)
{ {

Loading…
Cancel
Save