Browse Source

Don't return negative size from Measure.

In the case of a negative margin larger than the available size.
Steven Kirk 10 years ago
parent
commit
8e2830ad05
2 changed files with 62 additions and 1 deletions
  1. 11 1
      src/Perspex.Layout/Layoutable.cs
  2. 51 0
      tests/Perspex.Layout.UnitTests/MeasureTests.cs

+ 11 - 1
src/Perspex.Layout/Layoutable.cs

@@ -472,7 +472,7 @@ namespace Perspex.Layout
                 height = Math.Min(height, MaxHeight);
                 height = Math.Max(height, MinHeight);
 
-                return new Size(width, height).Inflate(Margin);
+                return NonNegative(new Size(width, height).Inflate(Margin));
             }
             else
             {
@@ -649,6 +649,16 @@ namespace Perspex.Layout
                 double.IsNaN(size.Width) || double.IsNaN(size.Height);
         }
 
+        /// <summary>
+        /// Ensures neither component of a <see cref="Size"/> is negative.
+        /// </summary>
+        /// <param name="size">The size.</param>
+        /// <returns>The non-negative size.</returns>
+        private static Size NonNegative(Size size)
+        {
+            return new Size(Math.Max(size.Width, 0), Math.Max(size.Height, 0));
+        }
+
         /// <summary>
         /// Gets the layout root, together with its distance.
         /// </summary>

+ 51 - 0
tests/Perspex.Layout.UnitTests/MeasureTests.cs

@@ -0,0 +1,51 @@
+// Copyright (c) The Perspex Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using Perspex.Controls;
+using Xunit;
+
+namespace Perspex.Layout.UnitTests
+{
+    public class MeasureTests
+    {
+        [Fact]
+        public void Negative_Margin_Larger_Than_Constraint_Should_Request_Width_0()
+        {
+            Control target;
+
+            var outer = new Decorator
+            {
+                Width = 100,
+                Height = 100,
+                Child = target = new Control
+                {
+                    Margin = new Thickness(-100, 0, 0, 0),
+                }
+            };
+
+            outer.Measure(Size.Infinity);
+
+            Assert.Equal(0, target.DesiredSize.Width);
+        }
+
+        [Fact]
+        public void Negative_Margin_Larger_Than_Constraint_Should_Request_Height_0()
+        {
+            Control target;
+
+            var outer = new Decorator
+            {
+                Width = 100,
+                Height = 100,
+                Child = target = new Control
+                {
+                    Margin = new Thickness(0, -100, 0, 0),
+                }
+            };
+
+            outer.Measure(Size.Infinity);
+
+            Assert.Equal(0, target.DesiredSize.Height);
+        }
+    }
+}