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);
+ }
+ }
+}