diff --git a/src/Avalonia.Controls/Image.cs b/src/Avalonia.Controls/Image.cs index 43c8fbcbb4..f6f11aa9ad 100644 --- a/src/Avalonia.Controls/Image.cs +++ b/src/Avalonia.Controls/Image.cs @@ -63,10 +63,10 @@ namespace Avalonia.Controls Vector scale = Stretch.CalculateScaling(Bounds.Size, sourceSize); Size scaledSize = sourceSize * scale; Rect destRect = viewPort - .CenterIn(new Rect(scaledSize)) + .CenterRect(new Rect(scaledSize)) .Intersect(viewPort); Rect sourceRect = new Rect(sourceSize) - .CenterIn(new Rect(destRect.Size / scale)); + .CenterRect(new Rect(destRect.Size / scale)); context.DrawImage(source, 1, sourceRect, destRect); } diff --git a/src/Avalonia.Visuals/Rect.cs b/src/Avalonia.Visuals/Rect.cs index 0d6aadbcaa..0132c5e8a3 100644 --- a/src/Avalonia.Visuals/Rect.cs +++ b/src/Avalonia.Visuals/Rect.cs @@ -238,7 +238,7 @@ namespace Avalonia /// /// The rectangle to center. /// The centered rectangle. - public Rect CenterIn(Rect rect) + public Rect CenterRect(Rect rect) { return new Rect( _x + ((_width - rect._width) / 2), @@ -401,6 +401,32 @@ namespace Avalonia return new Rect(Position + offset, Size); } + /// + /// Gets the union of two rectangles. + /// + /// The other rectangle. + /// The union. + public Rect Union(Rect rect) + { + if (IsEmpty) + { + return rect; + } + else if (rect.IsEmpty) + { + return this; + } + else + { + var x1 = Math.Min(this.X, rect.X); + var x2 = Math.Max(this.Right, rect.Right); + var y1 = Math.Min(this.Y, rect.Y); + var y2 = Math.Max(this.Bottom, rect.Bottom); + + return new Rect(new Point(x1, y1), new Point(x2, y2)); + } + } + /// /// Returns a new with the specified X position. /// diff --git a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj index 9e7f739a1c..b5b6dbd404 100644 --- a/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj +++ b/tests/Avalonia.Visuals.UnitTests/Avalonia.Visuals.UnitTests.csproj @@ -80,6 +80,7 @@ + diff --git a/tests/Avalonia.Visuals.UnitTests/RectTests.cs b/tests/Avalonia.Visuals.UnitTests/RectTests.cs new file mode 100644 index 0000000000..6e3f654bfb --- /dev/null +++ b/tests/Avalonia.Visuals.UnitTests/RectTests.cs @@ -0,0 +1,42 @@ +// Copyright (c) The Avalonia Project. All rights reserved. +// Licensed under the MIT license. See licence.md file in the project root for full license information. + +using Xunit; + +namespace Avalonia.Visuals.UnitTests +{ + public class RectTests + { + [Fact] + public void Union_Should_Return_Correct_Value_For_Intersecting_Rects() + { + var result = new Rect(0, 0, 100, 100).Union(new Rect(50, 50, 100, 100)); + + Assert.Equal(new Rect(0, 0, 150, 150), result); + } + + [Fact] + public void Union_Should_Return_Correct_Value_For_NonIntersecting_Rects() + { + var result = new Rect(0, 0, 100, 100).Union(new Rect(150, 150, 100, 100)); + + Assert.Equal(new Rect(0, 0, 250, 250), result); + } + + [Fact] + public void Union_Should_Ignore_Empty_This_rect() + { + var result = new Rect(0, 0, 0, 0).Union(new Rect(150, 150, 100, 100)); + + Assert.Equal(new Rect(150, 150, 100, 100), result); + } + + [Fact] + public void Union_Should_Ignore_Empty_Other_rect() + { + var result = new Rect(0, 0, 100, 100).Union(new Rect(150, 150, 0, 0)); + + Assert.Equal(new Rect(0, 0, 100, 100), result); + } + } +}