diff --git a/src/Avalonia.Base/Layout/LayoutHelper.cs b/src/Avalonia.Base/Layout/LayoutHelper.cs index d24be57d2ba..404d19906a7 100644 --- a/src/Avalonia.Base/Layout/LayoutHelper.cs +++ b/src/Avalonia.Base/Layout/LayoutHelper.cs @@ -36,11 +36,28 @@ public static Size ApplyLayoutConstraints(ILayoutable control, Size constraints) public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickness padding, Thickness borderThickness) { - return MeasureChild(control, availableSize, padding + borderThickness); + if (IsParentLayoutRounded(control, out double scale)) + { + padding = RoundLayoutThickness(padding, scale, scale); + borderThickness = RoundLayoutThickness(borderThickness, scale, scale); + } + + if (control != null) + { + control.Measure(availableSize.Deflate(padding + borderThickness)); + return control.DesiredSize.Inflate(padding + borderThickness); + } + + return new Size().Inflate(padding + borderThickness); } public static Size MeasureChild(ILayoutable? control, Size availableSize, Thickness padding) { + if (IsParentLayoutRounded(control, out double scale)) + { + padding = RoundLayoutThickness(padding, scale, scale); + } + if (control != null) { control.Measure(availableSize.Deflate(padding)); @@ -137,7 +154,7 @@ public static double GetLayoutScale(ILayoutable control) /// /// Rounds a size to integer values for layout purposes, compensating for high DPI screen - /// coordinates. + /// coordinates by rounding the size up to the nearest pixel. /// /// Input size. /// DPI along x-dimension. @@ -149,9 +166,9 @@ public static double GetLayoutScale(ILayoutable control) /// associated with the UseLayoutRounding property and should not be used as a general rounding /// utility. /// - public static Size RoundLayoutSize(Size size, double dpiScaleX, double dpiScaleY) + public static Size RoundLayoutSizeUp(Size size, double dpiScaleX, double dpiScaleY) { - return new Size(RoundLayoutValue(size.Width, dpiScaleX), RoundLayoutValue(size.Height, dpiScaleY)); + return new Size(RoundLayoutValueUp(size.Width, dpiScaleX), RoundLayoutValueUp(size.Height, dpiScaleY)); } /// @@ -178,10 +195,9 @@ public static Thickness RoundLayoutThickness(Thickness thickness, double dpiScal ); } - - /// - /// Calculates the value to be used for layout rounding at high DPI. + /// Calculates the value to be used for layout rounding at high DPI by rounding the value + /// up or down to the nearest pixel. /// /// Input value to be rounded. /// Ratio of screen's DPI to layout DPI @@ -217,7 +233,46 @@ public static double RoundLayoutValue(double value, double dpiScale) return newValue; } - + + /// + /// Calculates the value to be used for layout rounding at high DPI by rounding the value up + /// to the nearest pixel. + /// + /// Input value to be rounded. + /// Ratio of screen's DPI to layout DPI + /// Adjusted value that will produce layout rounding on screen at high dpi. + /// + /// This is a layout helper method. It takes DPI into account and also does not return + /// the rounded value if it is unacceptable for layout, e.g. Infinity or NaN. It's a helper + /// associated with the UseLayoutRounding property and should not be used as a general rounding + /// utility. + /// + public static double RoundLayoutValueUp(double value, double dpiScale) + { + double newValue; + + // If DPI == 1, don't use DPI-aware rounding. + if (!MathUtilities.IsOne(dpiScale)) + { + newValue = Math.Ceiling(value * dpiScale) / dpiScale; + + // If rounding produces a value unacceptable to layout (NaN, Infinity or MaxValue), + // use the original value. + if (double.IsNaN(newValue) || + double.IsInfinity(newValue) || + MathUtilities.AreClose(newValue, double.MaxValue)) + { + newValue = value; + } + } + else + { + newValue = Math.Ceiling(value); + } + + return newValue; + } + /// /// Calculates the min and max height for a control. Ported from WPF. /// diff --git a/src/Avalonia.Base/Layout/Layoutable.cs b/src/Avalonia.Base/Layout/Layoutable.cs index f30925f489e..101e867d566 100644 --- a/src/Avalonia.Base/Layout/Layoutable.cs +++ b/src/Avalonia.Base/Layout/Layoutable.cs @@ -548,6 +548,14 @@ protected virtual Size MeasureCore(Size availableSize) if (IsVisible) { var margin = Margin; + var useLayoutRounding = UseLayoutRounding; + var scale = 1.0; + + if (useLayoutRounding) + { + scale = LayoutHelper.GetLayoutScale(this); + margin = LayoutHelper.RoundLayoutThickness(margin, scale, scale); + } ApplyStyling(); ApplyTemplate(); @@ -584,16 +592,14 @@ protected virtual Size MeasureCore(Size availableSize) height = Math.Min(height, MaxHeight); height = Math.Max(height, MinHeight); - width = Math.Min(width, availableSize.Width); - height = Math.Min(height, availableSize.Height); - - if (UseLayoutRounding) + if (useLayoutRounding) { - var scale = LayoutHelper.GetLayoutScale(this); - width = LayoutHelper.RoundLayoutValue(width, scale); - height = LayoutHelper.RoundLayoutValue(height, scale); + (width, height) = LayoutHelper.RoundLayoutSizeUp(new Size(width, height), scale, scale); } + width = Math.Min(width, availableSize.Width); + height = Math.Min(height, availableSize.Height); + return NonNegative(new Size(width, height).Inflate(margin)); } else @@ -678,8 +684,8 @@ protected virtual void ArrangeCore(Rect finalRect) if (useLayoutRounding) { - size = LayoutHelper.RoundLayoutSize(size, scale, scale); - availableSizeMinusMargins = LayoutHelper.RoundLayoutSize(availableSizeMinusMargins, scale, scale); + size = LayoutHelper.RoundLayoutSizeUp(size, scale, scale); + availableSizeMinusMargins = LayoutHelper.RoundLayoutSizeUp(availableSizeMinusMargins, scale, scale); } size = ArrangeOverride(size).Constrain(size); diff --git a/src/Avalonia.Base/Point.cs b/src/Avalonia.Base/Point.cs index fbdf0db8001..0c789ff20fc 100644 --- a/src/Avalonia.Base/Point.cs +++ b/src/Avalonia.Base/Point.cs @@ -188,7 +188,7 @@ public static Point Parse(string s) } /// - /// Returns a boolean indicating whether the point is equal to the other given point. + /// Returns a boolean indicating whether the point is equal to the other given point (bitwise). /// /// The other point to test equality against. /// True if this point is equal to other; False otherwise. @@ -200,6 +200,18 @@ public bool Equals(Point other) // ReSharper enable CompareOfFloatsByEqualityOperator } + /// + /// Returns a boolean indicating whether the point is equal to the other given point + /// (numerically). + /// + /// The other point to test equality against. + /// True if this point is equal to other; False otherwise. + public bool NearlyEquals(Point other) + { + return MathUtilities.AreClose(_x, other._x) && + MathUtilities.AreClose(_y, other._y); + } + /// /// Checks for equality between a point and an object. /// diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs index f3ea48ff80d..c415f477d4d 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs @@ -855,7 +855,7 @@ internal void ComputeLayoutRoundedWidth(double leftEdge) if (OwningGrid != null && OwningGrid.UseLayoutRounding) { var scale = LayoutHelper.GetLayoutScale(HeaderCell); - var roundSize = LayoutHelper.RoundLayoutSize(new Size(leftEdge + ActualWidth, 1), scale, scale); + var roundSize = LayoutHelper.RoundLayoutSizeUp(new Size(leftEdge + ActualWidth, 1), scale, scale); LayoutRoundedWidth = roundSize.Width - leftEdge; } else diff --git a/src/Avalonia.Controls/Converters/MenuScrollingVisibilityConverter.cs b/src/Avalonia.Controls/Converters/MenuScrollingVisibilityConverter.cs index 6ab2f4c5172..9d859a753af 100644 --- a/src/Avalonia.Controls/Converters/MenuScrollingVisibilityConverter.cs +++ b/src/Avalonia.Controls/Converters/MenuScrollingVisibilityConverter.cs @@ -26,7 +26,7 @@ public class MenuScrollingVisibilityConverter : IMultiValueConverter if (visibility == ScrollBarVisibility.Auto) { - if (extent == viewport) + if (MathUtilities.AreClose(extent, viewport)) { return false; } diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs index 12a8dd747da..39888c12396 100644 --- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs +++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs @@ -635,8 +635,8 @@ internal Size ArrangeOverrideImpl(Size finalSize, Vector offset) if (useLayoutRounding) { - sizeForChild = LayoutHelper.RoundLayoutSize(sizeForChild, scale, scale); - availableSize = LayoutHelper.RoundLayoutSize(availableSize, scale, scale); + sizeForChild = LayoutHelper.RoundLayoutSizeUp(sizeForChild, scale, scale); + availableSize = LayoutHelper.RoundLayoutSizeUp(availableSize, scale, scale); } switch (horizontalContentAlignment) diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests.cs index 184aada6cde..c4b07950221 100644 --- a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests.cs +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests.cs @@ -173,37 +173,6 @@ public void Attaching_Control_To_Tree_Invalidates_Parent_Measure() target.Verify(x => x.InvalidateMeasure(root), Times.Once()); } - [Theory] - [InlineData(16, 6, 5.333333333333333)] - [InlineData(18, 10, 4)] - public void UseLayoutRounding_Arranges_Center_Alignment_Correctly_With_Fractional_Scaling( - double containerWidth, - double childWidth, - double expectedX) - { - Border target; - var root = new TestRoot - { - LayoutScaling = 1.5, - UseLayoutRounding = true, - Child = new Decorator - { - Width = containerWidth, - Height = 100, - Child = target = new Border - { - Width = childWidth, - HorizontalAlignment = HorizontalAlignment.Center, - } - } - }; - - root.Measure(new Size(100, 100)); - root.Arrange(new Rect(target.DesiredSize)); - - Assert.Equal(new Rect(expectedX, 0, childWidth, 100), target.Bounds); - } - [Fact] public void LayoutUpdated_Is_Called_At_End_Of_Layout_Pass() { diff --git a/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_LayoutRounding.cs b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_LayoutRounding.cs new file mode 100644 index 00000000000..77f1a8882d0 --- /dev/null +++ b/tests/Avalonia.Base.UnitTests/Layout/LayoutableTests_LayoutRounding.cs @@ -0,0 +1,140 @@ +using Avalonia.Controls; +using Avalonia.Layout; +using Avalonia.UnitTests; +using Xunit; +using Xunit.Sdk; + +namespace Avalonia.Base.UnitTests.Layout +{ + public class LayoutableTests_LayoutRounding + { + [Theory] + [InlineData(100, 100)] + [InlineData(101, 101.33333333333333)] + [InlineData(103, 103.33333333333333)] + public void Measure_Adjusts_DesiredSize_Upwards_When_Constraint_Allows(double desiredSize, double expectedSize) + { + var target = new TestLayoutable(new Size(desiredSize, desiredSize)); + var root = CreateRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + Assert.Equal(new Size(expectedSize, expectedSize), target.DesiredSize); + } + + [Fact] + public void Measure_Constrains_Adjusted_DesiredSize_To_Constraint() + { + var target = new TestLayoutable(new Size(101, 101)); + var root = CreateRoot(1.5, target, constraint: new Size(101, 101)); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // Desired width/height with layout rounding is 101.3333 but constraint is 101,101 so + // layout rounding should be ignored. + Assert.Equal(new Size(101, 101), target.DesiredSize); + } + + [Fact] + public void Measure_Adjusts_DesiredSize_Upwards_When_Margin_Present() + { + var target = new TestLayoutable(new Size(101, 101), margin: 1); + var root = CreateRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel margin is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Final size = 101.3333 + 2.6666 = 104 + AssertEqual(new Size(104, 104), target.DesiredSize); + } + + [Fact] + public void Arrange_Adjusts_Bounds_Upwards_With_Margin() + { + var target = new TestLayoutable(new Size(101, 101), margin: 1); + var root = CreateRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel margin is rounded up to 1.3333 + // - Size of 101 gets rounded up to 101.3333 + AssertEqual(new Point(1.3333333333333333, 1.3333333333333333), target.Bounds.Position); + AssertEqual(new Size(101.33333333333333, 101.33333333333333), target.Bounds.Size); + } + + [Theory] + [InlineData(16, 6, 5.333333333333333)] + [InlineData(18, 10, 4)] + public void Arranges_Center_Alignment_Correctly_With_Fractional_Scaling( + double containerWidth, + double childWidth, + double expectedX) + { + Border target; + var root = new TestRoot + { + LayoutScaling = 1.5, + UseLayoutRounding = true, + Child = new Decorator + { + Width = containerWidth, + Height = 100, + Child = target = new Border + { + Width = childWidth, + HorizontalAlignment = HorizontalAlignment.Center, + } + } + }; + + root.Measure(new Size(100, 100)); + root.Arrange(new Rect(target.DesiredSize)); + + Assert.Equal(new Rect(expectedX, 0, childWidth, 100), target.Bounds); + } + + private static TestRoot CreateRoot( + double scaling, + Control child, + Size? constraint = null) + { + return new TestRoot + { + LayoutScaling = scaling, + UseLayoutRounding = true, + Child = child, + ClientSize = constraint ?? new Size(1000, 1000), + }; + } + + private static void AssertEqual(Point expected, Point actual) + { + if (!expected.NearlyEquals(actual)) + { + throw new EqualException(expected, actual); + } + } + + private static void AssertEqual(Size expected, Size actual) + { + if (!expected.NearlyEquals(actual)) + { + throw new EqualException(expected, actual); + } + } + + private class TestLayoutable : Control + { + private Size _desiredSize; + + public TestLayoutable(Size desiredSize, double margin = 0) + { + _desiredSize = desiredSize; + Margin = new Thickness(margin); + } + + protected override Size MeasureOverride(Size availableSize) => _desiredSize; + } + } +} diff --git a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs index 5cc9f57c8ee..879de9fca57 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/SceneGraph/SceneBuilderTests.cs @@ -838,6 +838,7 @@ public void Resizing_Scene_Should_Add_DirtyRects() Canvas canvas; var tree = new TestRoot { + ClientSize = new Size(100, 100), Child = decorator = new Decorator { Margin = new Thickness(0, 10, 0, 0), diff --git a/tests/Avalonia.Controls.UnitTests/BorderTests.cs b/tests/Avalonia.Controls.UnitTests/BorderTests.cs index ab33eaaff9d..7af7d1cee2a 100644 --- a/tests/Avalonia.Controls.UnitTests/BorderTests.cs +++ b/tests/Avalonia.Controls.UnitTests/BorderTests.cs @@ -1,6 +1,8 @@ +using Avalonia.Layout; using Avalonia.Media; using Avalonia.Rendering; using Avalonia.UnitTests; +using Avalonia.VisualTree; using Moq; using Xunit; @@ -60,5 +62,68 @@ public void Changing_Background_Brush_Color_Should_Invalidate_Visual() renderer.Verify(x => x.AddDirty(target), Times.Once); } + + public class UseLayoutRounding + { + [Fact] + public void Measure_Rounds_Padding() + { + var target = new Border + { + Padding = new Thickness(1), + Child = new Canvas + { + Width = 101, + Height = 101, + } + }; + + var root = CreatedRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel padding is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Desired size = 101.3333 + 2.6666 = 104 + Assert.Equal(new Size(104, 104), target.DesiredSize); + } + + [Fact] + public void Measure_Rounds_BorderThickness() + { + var target = new Border + { + BorderThickness = new Thickness(1), + Child = new Canvas + { + Width = 101, + Height = 101, + } + }; + + var root = CreatedRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel border thickness is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Desired size = 101.3333 + 2.6666 = 104 + Assert.Equal(new Size(104, 104), target.DesiredSize); + } + + private static TestRoot CreatedRoot( + double scaling, + Control child, + Size? constraint = null) + { + return new TestRoot + { + LayoutScaling = scaling, + UseLayoutRounding = true, + Child = child, + ClientSize = constraint ?? new Size(1000, 1000), + }; + } + } } } diff --git a/tests/Avalonia.Controls.UnitTests/DecoratorTests.cs b/tests/Avalonia.Controls.UnitTests/DecoratorTests.cs index 65749efbf91..fe58cd4c7f9 100644 --- a/tests/Avalonia.Controls.UnitTests/DecoratorTests.cs +++ b/tests/Avalonia.Controls.UnitTests/DecoratorTests.cs @@ -1,6 +1,7 @@ using System.Collections.Specialized; using System.Linq; using Avalonia.LogicalTree; +using Avalonia.UnitTests; using Xunit; namespace Avalonia.Controls.UnitTests @@ -116,5 +117,45 @@ public void Measure_Should_Return_Padding_When_No_Child_Present() Assert.Equal(new Size(16, 16), target.DesiredSize); } + + public class UseLayoutRounding + { + [Fact] + public void Measure_Rounds_Padding() + { + var target = new Decorator + { + Padding = new Thickness(1), + Child = new Canvas + { + Width = 101, + Height = 101, + } + }; + + var root = CreatedRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel padding is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Desired size = 101.3333 + 2.6666 = 104 + Assert.Equal(new Size(104, 104), target.DesiredSize); + } + + private static TestRoot CreatedRoot( + double scaling, + Control child, + Size? constraint = null) + { + return new TestRoot + { + LayoutScaling = scaling, + UseLayoutRounding = true, + Child = child, + ClientSize = constraint ?? new Size(1000, 1000), + }; + } + } } } diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs index ed44fbfc325..e82050528fc 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs @@ -1,5 +1,6 @@ using Avalonia.Controls.Presenters; using Avalonia.Layout; +using Avalonia.UnitTests; using Xunit; namespace Avalonia.Controls.UnitTests.Presenters @@ -232,5 +233,68 @@ public void Child_Arrange_With_Zero_Height_When_Padding_Height_Greater_Than_Chil Assert.Equal(new Rect(32, 32, 0, 0), content.Bounds); } + + public class UseLayoutRounding + { + [Fact] + public void Measure_Rounds_Padding() + { + var target = new ContentPresenter + { + Padding = new Thickness(1), + Content = new Canvas + { + Width = 101, + Height = 101, + } + }; + + var root = CreatedRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel padding is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Desired size = 101.3333 + 2.6666 = 104 + Assert.Equal(new Size(104, 104), target.DesiredSize); + } + + [Fact] + public void Measure_Rounds_BorderThickness() + { + var target = new ContentPresenter + { + BorderThickness = new Thickness(1), + Content = new Canvas + { + Width = 101, + Height = 101, + } + }; + + var root = CreatedRoot(1.5, target); + + root.LayoutManager.ExecuteInitialLayoutPass(); + + // - 1 pixel border thickness is rounded up to 1.3333; for both sides it is 2.6666 + // - Size of 101 gets rounded up to 101.3333 + // - Desired size = 101.3333 + 2.6666 = 104 + Assert.Equal(new Size(104, 104), target.DesiredSize); + } + + private static TestRoot CreatedRoot( + double scaling, + Control child, + Size? constraint = null) + { + return new TestRoot + { + LayoutScaling = scaling, + UseLayoutRounding = true, + Child = child, + ClientSize = constraint ?? new Size(1000, 1000), + }; + } + } } -} \ No newline at end of file +} diff --git a/tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs b/tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs index 59276a94d01..f4001a8ca10 100644 --- a/tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs +++ b/tests/Avalonia.Controls.UnitTests/Primitives/TrackTests.cs @@ -67,7 +67,7 @@ public void Should_Arrange_Thumb_In_Horizontal_Orientation() target.Measure(new Size(100, 100)); target.Arrange(new Rect(0, 0, 100, 100)); - Assert.Equal(new Rect(33, 0, 33, 12), thumb.Bounds); + Assert.Equal(new Rect(33, 0, 34, 12), thumb.Bounds); } [Fact] @@ -92,7 +92,7 @@ public void Should_Arrange_Thumb_In_Vertical_Orientation() target.Measure(new Size(100, 100)); target.Arrange(new Rect(0, 0, 100, 100)); - Assert.Equal(new Rect(0, 33, 12, 33), thumb.Bounds); + Assert.Equal(new Rect(0, 33, 12, 34), thumb.Bounds); } [Fact] diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs index 4601dd7e5bb..41e29a85c42 100644 --- a/tests/Avalonia.UnitTests/TestRoot.cs +++ b/tests/Avalonia.UnitTests/TestRoot.cs @@ -41,7 +41,7 @@ public TestRoot(bool useGlobalStyles, IControl child) Child = child; } - public Size ClientSize { get; set; } = new Size(100, 100); + public Size ClientSize { get; set; } = new Size(1000, 1000); public Size MaxClientSize { get; set; } = Size.Infinity; @@ -110,5 +110,10 @@ void Visit(StyledElement element, bool force = false) } Visit(this, true); } + + protected override Size MeasureOverride(Size availableSize) + { + return base.MeasureOverride(ClientSize); + } } } diff --git a/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png index e8624fa457f..8ca7acb8458 100644 Binary files a/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png and b/tests/TestFiles/Direct2D1/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png differ diff --git a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png index 7bd622050e0..a76c6a5b2a8 100644 Binary files a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png differ