diff --git a/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs b/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs new file mode 100644 index 000000000..f4639a4b8 --- /dev/null +++ b/osu.Framework.Tests/Visual/Drawables/TestSceneAutoSize.cs @@ -0,0 +1,93 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Testing; +using osu.Framework.Utils; +using osuTK; + +namespace osu.Framework.Tests.Visual.Drawables +{ + [HeadlessTest] + public partial class TestSceneAutoSize : TestScene + { + private static readonly object[][] scales = Enumerable.Range(0, 10).Select(i => new object[] { MathF.Pow(10, -i) }).ToArray(); + + [TestCaseSource(nameof(scales))] + public void TestAlmostZeroXScale(float scale) + { + Container autoSizeContainer = null!; + Container outerContainer; + + AddStep("add box", () => + { + Add(outerContainer = new Container + { + Name = "outer container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Child = autoSizeContainer = new Container + { + Name = "autosize container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Child = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(128f), + } + } + }); + + outerContainer.Scale = new Vector2(scale, 2); + }); + + AddAssert("autosize container preserves width", () => autoSizeContainer.Width, () => Is.EqualTo(128).Within(Precision.FLOAT_EPSILON)); + } + + [TestCaseSource(nameof(scales))] + public void TestAlmostZeroYScale(float scale) + { + Container autoSizeContainer = null!; + Container outerContainer; + + AddStep("add box", () => + { + Add(outerContainer = new Container + { + Name = "outer container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + RelativePositionAxes = Axes.Both, + Child = autoSizeContainer = new Container + { + Name = "autosize container", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Child = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(128f), + } + } + }); + + outerContainer.Scale = new Vector2(2, scale); + }); + + AddAssert("autosize container preserves height", () => autoSizeContainer.Height, () => Is.EqualTo(128).Within(Precision.FLOAT_EPSILON)); + } + } +} diff --git a/osu.Framework/Graphics/BlendingParameters.cs b/osu.Framework/Graphics/BlendingParameters.cs index 1721dab3a..4cc7bd4ed 100644 --- a/osu.Framework/Graphics/BlendingParameters.cs +++ b/osu.Framework/Graphics/BlendingParameters.cs @@ -238,6 +238,9 @@ namespace osu.Framework.Graphics return BlendingFactorSrc.OneMinusDstColor; case BlendingType.OneMinusSrcAlpha: + return BlendingFactorSrc.OneMinusSrcAlpha; + + case BlendingType.OneMinusSrcColor: return BlendingFactorSrc.OneMinusSrcColor; case BlendingType.SrcAlpha: diff --git a/osu.Framework/Graphics/DrawInfo.cs b/osu.Framework/Graphics/DrawInfo.cs index 44bd44602..050d6c5fa 100644 --- a/osu.Framework/Graphics/DrawInfo.cs +++ b/osu.Framework/Graphics/DrawInfo.cs @@ -52,8 +52,8 @@ namespace osu.Framework.Graphics if (scale != Vector2.One) { // Zero scale leads to unexpected input and autosize calculations, so it's clamped to a sane value. - if (scale.X == 0) scale.X = Precision.FLOAT_EPSILON; - if (scale.Y == 0) scale.Y = Precision.FLOAT_EPSILON; + if (Math.Abs(scale.X) < Precision.FLOAT_EPSILON) scale.X = Math.Sign(scale.X == 0 ? 1 : scale.X) * Precision.FLOAT_EPSILON; + if (Math.Abs(scale.Y) < Precision.FLOAT_EPSILON) scale.Y = Math.Sign(scale.Y == 0 ? 1 : scale.Y) * Precision.FLOAT_EPSILON; MatrixExtensions.ScaleFromLeft(ref Matrix, scale); MatrixExtensions.ScaleFromRight(ref MatrixInverse, Vector2.Divide(Vector2.One, scale));