diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml index 7cdbc9260..fca8e2733 100644 --- a/.github/workflows/create-release.yml +++ b/.github/workflows/create-release.yml @@ -42,7 +42,7 @@ jobs: - name: Setup Dotnet uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Build MonoGame.Extended run: dotnet build MonoGame.Extended.sln --nologo --verbosity minimal --configuration Release diff --git a/.github/workflows/pull-request-test.yml b/.github/workflows/pull-request-test.yml index ec0775e27..ca77e143f 100644 --- a/.github/workflows/pull-request-test.yml +++ b/.github/workflows/pull-request-test.yml @@ -26,7 +26,7 @@ jobs: - name: Setup DotNet uses: actions/setup-dotnet@v4 with: - dotnet-version: 6.0.x + dotnet-version: 8.0.x - name: Test MonoGame.Extended run: dotnet test MonoGame.Extended.sln --nologo --verbosity minimal --configuration Release diff --git a/CHANGELOG.md b/CHANGELOG.md index 1cc9117d3..08cd7d1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 > Unreleased changes exist in the current `develop` branch but have not been pushed as either a stable or prerelease NuGet package. > +## [4.0.3] +## Fixed +- Resoled issue where `Matrix3x2.Decompose` returned incorrect values for transformation [@Std-Enigma](https://github.com/Std-Enigma) [#941](https://github.com/craftworkgames/MonoGame.Extended/pull/941) +- Resolved bug in NinePatch where padding calculations were incorrect [@Dwergi](https://github.com/Dwergi) [#945](https://github.com/craftworkgames/MonoGame.Extended/pull/945) +- Resoled bug in `Texture2DExtensions.CreateNinePatch` where source rectangles were calculated that overlapped. [@greenstack](https://github.com/greenstack) [#948](https://github.com/craftworkgames/MonoGame.Extended/pull/948) + +## Changed +- `BitmapFont` uses `TitleContainer` to load stream of file [@Dwergi](https://github.com/Dwergi) [#946](https://github.com/craftworkgames/MonoGame.Extended/pull/946) +- Revert UV code for `Sprite.OriginNormalize`, resolving incorrect calculations [@kaltinril](https://github.com/kaltinril) [#951](https://github.com/craftworkgames/MonoGame.Extended/pull/951) + + ## [4.0.2] ### Fixed - Resolved issue when reading .particle files for a ParticleEffect that cause a recursion loop bug creating a stack overflow exception [@AristurtleDev](https://github.com/AristurtleDev) [#938](https://github.com/craftworkgames/MonoGame.Extended/pull/938) diff --git a/Directory.Build.props b/Directory.Build.props index 66e4f5667..88f56f6dd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,7 +7,7 @@ - 4.0.2 + 4.0.3 -prerelease .$(BUILD_NUMBER) $(MonoGameExtendedVersion)$(IsPrerelease)$(BuildNumber) diff --git a/source/MonoGame.Extended/BitmapFonts/BitmapFont.cs b/source/MonoGame.Extended/BitmapFonts/BitmapFont.cs index b982c5718..b174b569e 100644 --- a/source/MonoGame.Extended/BitmapFonts/BitmapFont.cs +++ b/source/MonoGame.Extended/BitmapFonts/BitmapFont.cs @@ -364,13 +364,19 @@ public void Reset() public static BitmapFont FromFile(GraphicsDevice graphicsDevice, string path) { - using FileStream stream = File.OpenRead(path); - return FromStream(graphicsDevice, stream); + using Stream stream = TitleContainer.OpenStream(path); + return FromStream(graphicsDevice, stream, path); } + [Obsolete("Use the FromStream() overload that takes an explicit name.")] public static BitmapFont FromStream(GraphicsDevice graphicsDevice, FileStream stream) { - var bmfFile = BitmapFontFileReader.Read(stream); + return FromStream(graphicsDevice, stream, stream.Name); + } + + public static BitmapFont FromStream(GraphicsDevice graphicsDevice, Stream stream, string name) + { + var bmfFile = BitmapFontFileReader.Read(stream, name); // Load page textures Dictionary pages = new Dictionary(); @@ -379,7 +385,7 @@ public static BitmapFont FromStream(GraphicsDevice graphicsDevice, FileStream st if (!pages.ContainsKey(bmfFile.Pages[i])) { string texturePath = Path.Combine(Path.GetDirectoryName(bmfFile.Path), bmfFile.Pages[i]); - using (Stream textureStream = File.OpenRead(texturePath)) + using (Stream textureStream = TitleContainer.OpenStream(texturePath)) { Texture2D texture = Texture2D.FromStream(graphicsDevice, textureStream); pages.Add(bmfFile.Pages[i], texture); diff --git a/source/MonoGame.Extended/Content/BitmapFonts/BitmapFontFileReader.cs b/source/MonoGame.Extended/Content/BitmapFonts/BitmapFontFileReader.cs index 6f5784772..bb9a444cd 100644 --- a/source/MonoGame.Extended/Content/BitmapFonts/BitmapFontFileReader.cs +++ b/source/MonoGame.Extended/Content/BitmapFonts/BitmapFontFileReader.cs @@ -28,18 +28,33 @@ public static class BitmapFontFileReader public static BitmapFontFileContent Read(string path) { using var stream = File.OpenRead(path); - return Read(stream); + return Read(stream, path); } /// /// Reads the content of the font file at the path specified. /// - /// A containing the font file contents to read. + /// A containing the font file contents to read. /// A instance containing the results of the read operation. /// /// Thrown if the header for the file contents does not match a known header format. /// + [Obsolete("Use the overload that takes an explicit name parameter.")] public static BitmapFontFileContent Read(FileStream stream) + { + return Read(stream, stream.Name); + } + + /// + /// Reads the content of the font file at the path specified. + /// + /// A containing the font file contents to read. + /// The name or path that uniquely identifies this . + /// A instance containing the results of the read operation. + /// + /// Thrown if the header for the file contents does not match a known header format. + /// + public static BitmapFontFileContent Read(Stream stream, string name) { long position = stream.Position; var sig = stream.ReadByte(); @@ -60,7 +75,7 @@ public static BitmapFontFileContent Read(FileStream stream) _ => throw new InvalidOperationException("This does not appear to be a valid BMFont file!") }; - bmfFile.Path = stream.Name; + bmfFile.Path = name; return bmfFile; } diff --git a/source/MonoGame.Extended/Graphics/NinePatch.cs b/source/MonoGame.Extended/Graphics/NinePatch.cs index 25d1ce62c..7a9e1069a 100644 --- a/source/MonoGame.Extended/Graphics/NinePatch.cs +++ b/source/MonoGame.Extended/Graphics/NinePatch.cs @@ -62,6 +62,9 @@ public class NinePatch /// public string Name { get; } + /// + /// The size of the border patches around the middle patch. + /// public Thickness Padding { get; } /// @@ -90,7 +93,11 @@ public NinePatch(Texture2DRegion[] patches) : this(patches, null) { } /// /// Initializes a new instance of the class with the specified patches and name. /// - /// An array of nine objects. + /// + /// An array of nine objects. + /// The top, left, bottom and right regions must to be of exactly the same size. + /// Mid patches can be as small as 1x1. + /// /// /// The name of the nine-patch. If null or empty, a default name will be generated based on the texture name of the /// top-left patch. @@ -113,8 +120,11 @@ public NinePatch(Texture2DRegion[] patches, string name) } _patches = patches; - Rectangle mid = patches[NinePatch.Middle].Bounds; - Padding = new Thickness(mid.Left, mid.Top, mid.Right, mid.Bottom); + + Size topLeft = patches[NinePatch.TopLeft].Size; + Size bottomRight = patches[NinePatch.BottomRight].Size; + Padding = new Thickness(topLeft.Width, topLeft.Height, bottomRight.Width, bottomRight.Height); + Name = name; } } diff --git a/source/MonoGame.Extended/Graphics/Sprite.cs b/source/MonoGame.Extended/Graphics/Sprite.cs index 096f89510..09e928e83 100644 --- a/source/MonoGame.Extended/Graphics/Sprite.cs +++ b/source/MonoGame.Extended/Graphics/Sprite.cs @@ -79,18 +79,8 @@ public class Sprite : IColorable /// public Vector2 OriginNormalized { - get - { - float normalizedX = (Origin.X - TextureRegion.LeftUV) / (TextureRegion.RightUV - TextureRegion.LeftUV); - float normalizedY = (Origin.Y - TextureRegion.TopUV) / (TextureRegion.BottomUV - TextureRegion.TopUV); - return new Vector2(normalizedX, normalizedY); - } - set - { - float actualX = value.X * (TextureRegion.RightUV - TextureRegion.LeftUV) + TextureRegion.LeftUV; - float actualY = value.Y * (TextureRegion.BottomUV - TextureRegion.TopUV) + TextureRegion.TopUV; - Origin = new Vector2(actualX, actualY); - } + get { return new Vector2(Origin.X / TextureRegion.Width, Origin.Y / TextureRegion.Height); } + set { Origin = new Vector2(value.X * TextureRegion.Width, value.Y * TextureRegion.Height); } } /// diff --git a/source/MonoGame.Extended/Graphics/Texture2DRegion.Extensions.cs b/source/MonoGame.Extended/Graphics/Texture2DRegion.Extensions.cs index cefe98e07..a0fbce90e 100644 --- a/source/MonoGame.Extended/Graphics/Texture2DRegion.Extensions.cs +++ b/source/MonoGame.Extended/Graphics/Texture2DRegion.Extensions.cs @@ -141,18 +141,20 @@ public static NinePatch CreateNinePatch(this Texture2DRegion textureRegion, int int middleWidth = textureRegion.Width - leftPadding - rightPadding; int middleHeight = textureRegion.Height - topPadding - bottomPadding; + int rightX = textureRegion.Width - rightPadding; + int bottomY = textureRegion.Height - bottomPadding; patches[NinePatch.TopLeft] = textureRegion.GetSubregion(0, 0, leftPadding, topPadding); patches[NinePatch.TopMiddle] = textureRegion.GetSubregion(leftPadding, 0, middleWidth, topPadding); - patches[NinePatch.TopRight] = textureRegion.GetSubregion(middleWidth, 0, rightPadding, topPadding); + patches[NinePatch.TopRight] = textureRegion.GetSubregion(rightX, 0, rightPadding, topPadding); patches[NinePatch.MiddleLeft] = textureRegion.GetSubregion(0, topPadding, leftPadding, middleHeight); patches[NinePatch.Middle] = textureRegion.GetSubregion(leftPadding, topPadding, middleWidth, middleHeight); - patches[NinePatch.MiddleRight] = textureRegion.GetSubregion(middleWidth, topPadding, rightPadding, middleHeight); + patches[NinePatch.MiddleRight] = textureRegion.GetSubregion(rightX, topPadding, rightPadding, middleHeight); - patches[NinePatch.BottomLeft] = textureRegion.GetSubregion(0, middleHeight, leftPadding, bottomPadding); - patches[NinePatch.BottomMiddle] = textureRegion.GetSubregion(leftPadding, middleHeight, middleWidth, bottomPadding); - patches[NinePatch.BottomRight] = textureRegion.GetSubregion(middleWidth, middleHeight, rightPadding, bottomPadding); + patches[NinePatch.BottomLeft] = textureRegion.GetSubregion(0, bottomY, leftPadding, bottomPadding); + patches[NinePatch.BottomMiddle] = textureRegion.GetSubregion(leftPadding, bottomY, middleWidth, bottomPadding); + patches[NinePatch.BottomRight] = textureRegion.GetSubregion(rightX, bottomY, rightPadding, bottomPadding); return new NinePatch(patches); } diff --git a/source/MonoGame.Extended/Math/Matrix3x2.cs b/source/MonoGame.Extended/Math/Matrix3x2.cs index 3a6d52098..94d997fde 100644 --- a/source/MonoGame.Extended/Math/Matrix3x2.cs +++ b/source/MonoGame.Extended/Math/Matrix3x2.cs @@ -298,7 +298,7 @@ public void Transform(in float x, in float y, ref Vector3 result) public void Decompose(out Vector2 translation, out float rotation, out Vector2 scale) { translation.X = M31; - translation.Y = M31; + translation.Y = M32; rotation = (float)Math.Atan2(M21, M11); diff --git a/tests/MonoGame.Extended.Tests/BitmapFonts/BitmapFontFileReaderTests.cs b/tests/MonoGame.Extended.Tests/BitmapFonts/BitmapFontFileReaderTests.cs index 72db9eff9..626deb3aa 100644 --- a/tests/MonoGame.Extended.Tests/BitmapFonts/BitmapFontFileReaderTests.cs +++ b/tests/MonoGame.Extended.Tests/BitmapFonts/BitmapFontFileReaderTests.cs @@ -102,8 +102,9 @@ private static BitmapFontFileContent CreateExpected() [Fact] public void Read_BinaryFile_Test() { - using FileStream stream = File.OpenRead("BitmapFonts/files/bmfont/test-font-binary.fnt"); - var actual = BitmapFontFileReader.Read(stream); + string path = "BitmapFonts/files/bmfont/test-font-binary.fnt"; + using FileStream stream = File.OpenRead(path); + var actual = BitmapFontFileReader.Read(stream, path); Assert.Equal(_expected.Header, actual.Header); Assert.Equal(_expected.Info, actual.Info); Assert.Equal(_expected.Common, actual.Common); @@ -116,8 +117,9 @@ public void Read_BinaryFile_Test() [Fact] public void Read_XmlFile_Test() { - using FileStream stream = File.OpenRead("BitmapFonts/files/bmfont/test-font-xml.fnt"); - var actual = BitmapFontFileReader.Read(stream); + string path = "BitmapFonts/files/bmfont/test-font-xml.fnt"; + using FileStream stream = File.OpenRead(path); + var actual = BitmapFontFileReader.Read(stream, path); Assert.Equal(_expected.Header, actual.Header); Assert.Equal(_expected.Info, actual.Info); Assert.Equal(_expected.Common, actual.Common); @@ -130,8 +132,9 @@ public void Read_XmlFile_Test() [Fact] public void Read_Text_Test() { - using FileStream stream = File.OpenRead("BitmapFonts/files/bmfont/test-font-text.fnt"); - var actual = BitmapFontFileReader.Read(stream); + string path = "BitmapFonts/files/bmfont/test-font-text.fnt"; + using FileStream stream = File.OpenRead(path); + var actual = BitmapFontFileReader.Read(stream, path); Assert.Equal(_expected.Header, actual.Header); Assert.Equal(_expected.Info, actual.Info); Assert.Equal(_expected.Common, actual.Common);