diff --git a/binding/Binding/Definitions.cs b/binding/Binding/Definitions.cs index de8ed406..390a9daf 100644 --- a/binding/Binding/Definitions.cs +++ b/binding/Binding/Definitions.cs @@ -1515,6 +1515,10 @@ namespace SkiaSharp set { bottom = value; } } + public int MidX => left + (Width / 2); + + public int MidY => top + (Height / 2); + public int Width => right - left; public int Height => bottom - top; @@ -1537,6 +1541,28 @@ namespace SkiaSharp } } + public SKRectI Standardized { + get { + if (left > right) { + if (top > bottom) { + return new SKRectI (right, bottom, left, top); + } else { + return new SKRectI (right, top, left, bottom); + } + } else { + if (top > bottom) { + return new SKRectI (left, bottom, right, top); + } else { + return new SKRectI (left, top, right, bottom); + } + } + } + } + + public SKRectI AspectFit (SKSizeI size) => Truncate (((SKRect)this).AspectFit (size)); + + public SKRectI AspectFill (SKSizeI size) => Truncate (((SKRect)this).AspectFill (size)); + public static SKRectI Ceiling (SKRect value) { int x, y, r, b; @@ -1767,6 +1793,10 @@ namespace SkiaSharp set { bottom = value; } } + public float MidX => left + (Width / 2f); + + public float MidY => top + (Height / 2f); + public float Width => right - left; public float Height => bottom - top; @@ -1789,6 +1819,52 @@ namespace SkiaSharp } } + public SKRect Standardized { + get { + if (left > right) { + if (top > bottom) { + return new SKRect (right, bottom, left, top); + } else { + return new SKRect (right, top, left, bottom); + } + } else { + if (top > bottom) { + return new SKRect (left, bottom, right, top); + } else { + return new SKRect (left, top, right, bottom); + } + } + } + } + + public SKRect AspectFit (SKSize size) => AspectResize (size, true); + + public SKRect AspectFill (SKSize size) => AspectResize (size, false); + + private SKRect AspectResize (SKSize size, bool fit) + { + if (size.Width == 0 || size.Height == 0 || Width == 0 || Height == 0) + return SKRect.Create (MidX, MidY, 0, 0); + + float aspectWidth = size.Width; + float aspectHeight = size.Height; + float imgAspect = aspectWidth / aspectHeight; + float fullRectAspect = Width / Height; + + bool compare = fit ? (fullRectAspect > imgAspect) : (fullRectAspect < imgAspect); + if (compare) { + aspectHeight = Height; + aspectWidth = aspectHeight * imgAspect; + } else { + aspectWidth = Width; + aspectHeight = aspectWidth / imgAspect; + } + float aspectLeft = MidX - (aspectWidth / 2f); + float aspectTop = MidY - (aspectHeight / 2f); + + return SKRect.Create (aspectLeft, aspectTop, aspectWidth, aspectHeight); + } + public static SKRect Inflate (SKRect rect, float x, float y) { var r = new SKRect (rect.left, rect.top, rect.right, rect.bottom); diff --git a/tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.csproj b/tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.csproj index c9e56131..dccc9e9b 100644 --- a/tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.csproj +++ b/tests/SkiaSharp.Desktop.Tests/SkiaSharp.Desktop.Tests.csproj @@ -110,6 +110,9 @@ SKColorTest.cs + + SKBasicTypesTest.cs + diff --git a/tests/Tests/SKBasicTypesTest.cs b/tests/Tests/SKBasicTypesTest.cs new file mode 100644 index 00000000..503ea891 --- /dev/null +++ b/tests/Tests/SKBasicTypesTest.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using NUnit.Framework; + +namespace SkiaSharp.Tests +{ + [TestFixture] + public class SKBasicTypesTest : SKTest + { + private const float EPSILON = 0.0001f; + + [Test] + public void RectanlgeHasCorrectProperties() + { + var rect = new SKRect(15, 25, 55, 75); + + Assert.AreEqual(15f, rect.Left); + Assert.AreEqual(25f, rect.Top); + Assert.AreEqual(55f, rect.Right); + Assert.AreEqual(75f, rect.Bottom); + + Assert.AreEqual(40f, rect.Width); + Assert.AreEqual(50f, rect.Height); + + Assert.AreEqual(35f, rect.MidX); + Assert.AreEqual(50f, rect.MidY); + } + + [Test] + public void RectanlgeInflatesCorrectly() + { + var rect = new SKRect(15, 25, 55, 75); + + Assert.AreEqual(15f, rect.Left); + Assert.AreEqual(25f, rect.Top); + Assert.AreEqual(55f, rect.Right); + Assert.AreEqual(75f, rect.Bottom); + + rect.Inflate(10, 20); + + Assert.AreEqual(5f, rect.Left); + Assert.AreEqual(5f, rect.Top); + Assert.AreEqual(65f, rect.Right); + Assert.AreEqual(95f, rect.Bottom); + } + + [Test] + public void RectanlgeStandardizeCorrectly() + { + var rect = new SKRect(5, 5, 15, 15); + Assert.AreEqual(10, rect.Width); + Assert.AreEqual(10, rect.Height); + + Assert.AreEqual(rect, rect.Standardized); + + var negW = new SKRect(15, 5, 5, 15); + Assert.AreEqual(-10, negW.Width); + Assert.AreEqual(10, negW.Height); + Assert.AreEqual(rect, negW.Standardized); + + var negH = new SKRect(5, 15, 15, 5); + Assert.AreEqual(10, negH.Width); + Assert.AreEqual(-10, negH.Height); + Assert.AreEqual(rect, negH.Standardized); + + var negWH = new SKRect(15, 15, 5, 5); + Assert.AreEqual(-10, negWH.Width); + Assert.AreEqual(-10, negWH.Height); + Assert.AreEqual(rect, negWH.Standardized); + } + + [Test] + public void RectanlgeAspectFitIsCorrect() + { + var bigRect = SKRect.Create(5, 5, 20, 20); + var tallSize = new SKSize(5, 10); + var wideSize = new SKSize(10, 5); + + var fitTall = bigRect.AspectFit(tallSize); + Assert.AreEqual(5 + 5, fitTall.Left); + Assert.AreEqual(5 + 0, fitTall.Top); + Assert.AreEqual(10, fitTall.Width); + Assert.AreEqual(20, fitTall.Height); + + var fitWide = bigRect.AspectFit(wideSize); + Assert.AreEqual(5 + 0, fitWide.Left); + Assert.AreEqual(5 + 5, fitWide.Top); + Assert.AreEqual(20, fitWide.Width); + Assert.AreEqual(10, fitWide.Height); + } + + [Test] + public void RectanlgeAspectFillIsCorrect() + { + var bigRect = SKRect.Create(5, 5, 20, 20); + var tallSize = new SKSize(5, 10); + var wideSize = new SKSize(10, 5); + + var fitTall = bigRect.AspectFill(tallSize); + Assert.AreEqual(5 + 0, fitTall.Left); + Assert.AreEqual(5 - 10, fitTall.Top); + Assert.AreEqual(20, fitTall.Width); + Assert.AreEqual(40, fitTall.Height); + + var fitWide = bigRect.AspectFill(wideSize); + Assert.AreEqual(5 - 10, fitWide.Left); + Assert.AreEqual(5 + 0, fitWide.Top); + Assert.AreEqual(40, fitWide.Width); + Assert.AreEqual(20, fitWide.Height); + } + } +}