1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 11:07:52 +08:00

Merge branch 'master' into swell-cheesing

This commit is contained in:
Dean Herbert 2023-10-05 23:08:21 +09:00 committed by GitHub
commit c66423279c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 15 deletions

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
@ -173,7 +174,7 @@ namespace osu.Game.Tests.Visual.Gameplay
string? filePath = null;
// Files starting with _ are temporary, created by CreateFileSafely call.
AddUntilStep("wait for export file", () => filePath = LocalStorage.GetFiles("exports").SingleOrDefault(f => !f.StartsWith("_", StringComparison.Ordinal)), () => Is.Not.Null);
AddUntilStep("wait for export file", () => filePath = LocalStorage.GetFiles("exports").SingleOrDefault(f => !Path.GetFileName(f).StartsWith("_", StringComparison.Ordinal)), () => Is.Not.Null);
AddAssert("filesize is non-zero", () =>
{
using (var stream = LocalStorage.GetStream(filePath))

View File

@ -3,14 +3,20 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Textures;
using osu.Framework.IO.Stores;
using osu.Framework.Testing;
using osu.Game.IO;
using osu.Game.Rulesets;
using osu.Game.Screens.Play;
using osu.Game.Skinning;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
namespace osu.Game.Tests.Visual.Gameplay
{
@ -23,6 +29,9 @@ namespace osu.Game.Tests.Visual.Gameplay
/// </remarks>
public partial class TestScenePlayerMaxDimensions : TestSceneAllRulesetPlayers
{
// scale textures to 4 times their size.
private const int scale_factor = 4;
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
{
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
@ -63,18 +72,66 @@ namespace osu.Game.Tests.Visual.Gameplay
remove { }
}
public override Texture? GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
{
var texture = base.GetTexture(componentName, wrapModeS, wrapModeT);
if (texture != null)
texture.ScaleAdjust /= 8f;
return texture;
}
public ISkin FindProvider(Func<ISkin, bool> lookupFunction) => this;
public IEnumerable<ISkin> AllSources => new[] { this };
protected override IResourceStore<TextureUpload> CreateTextureLoaderStore(IStorageResourceProvider resources, IResourceStore<byte[]> storage)
=> new UpscaledTextureLoaderStore(base.CreateTextureLoaderStore(resources, storage));
private class UpscaledTextureLoaderStore : IResourceStore<TextureUpload>
{
private readonly IResourceStore<TextureUpload>? textureStore;
public UpscaledTextureLoaderStore(IResourceStore<TextureUpload>? textureStore)
{
this.textureStore = textureStore;
}
public void Dispose()
{
textureStore?.Dispose();
}
public TextureUpload Get(string name)
{
var textureUpload = textureStore?.Get(name);
// NRT not enabled on framework side classes (IResourceStore / TextureLoaderStore), welp.
if (textureUpload == null)
return null!;
return upscale(textureUpload);
}
public async Task<TextureUpload> GetAsync(string name, CancellationToken cancellationToken = new CancellationToken())
{
// NRT not enabled on framework side classes (IResourceStore / TextureLoaderStore), welp.
if (textureStore == null)
return null!;
var textureUpload = await textureStore.GetAsync(name, cancellationToken).ConfigureAwait(false);
if (textureUpload == null)
return null!;
return await Task.Run(() => upscale(textureUpload), cancellationToken).ConfigureAwait(false);
}
private TextureUpload upscale(TextureUpload textureUpload)
{
var image = Image.LoadPixelData(textureUpload.Data.ToArray(), textureUpload.Width, textureUpload.Height);
// The original texture upload will no longer be returned or used.
textureUpload.Dispose();
image.Mutate(i => i.Resize(new Size(textureUpload.Width, textureUpload.Height) * scale_factor));
return new TextureUpload(image);
}
public Stream? GetStream(string name) => textureStore?.GetStream(name);
public IEnumerable<string> GetAvailableResources() => textureStore?.GetAvailableResources() ?? Array.Empty<string>();
}
}
}
}

View File

@ -9,6 +9,7 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osuTK;
@ -112,9 +113,11 @@ namespace osu.Game.Skinning
if (texture.DisplayWidth <= maxSize.X && texture.DisplayHeight <= maxSize.Y)
return texture;
// use scale adjust property for downscaling the texture in order to meet the specified maximum dimensions.
texture.ScaleAdjust *= Math.Max(texture.DisplayWidth / maxSize.X, texture.DisplayHeight / maxSize.Y);
return texture;
maxSize *= texture.ScaleAdjust;
var croppedTexture = texture.Crop(new RectangleF(texture.Width / 2f - maxSize.X / 2f, texture.Height / 2f - maxSize.Y / 2f, maxSize.X, maxSize.Y));
croppedTexture.ScaleAdjust = texture.ScaleAdjust;
return croppedTexture;
}
public static bool HasFont(this ISkin source, LegacyFont font)

View File

@ -88,7 +88,7 @@ namespace osu.Game.Skinning
}
Samples = samples;
Textures = new TextureStore(resources.Renderer, new MaxDimensionLimitedTextureLoaderStore(resources.CreateTextureLoaderStore(storage)));
Textures = new TextureStore(resources.Renderer, CreateTextureLoaderStore(resources, storage));
}
else
{
@ -171,6 +171,9 @@ namespace osu.Game.Skinning
}
}
protected virtual IResourceStore<TextureUpload> CreateTextureLoaderStore(IStorageResourceProvider resources, IResourceStore<byte[]> storage)
=> new MaxDimensionLimitedTextureLoaderStore(resources.CreateTextureLoaderStore(storage));
protected virtual void ParseConfigurationStream(Stream stream)
{
using (LineBufferedReader reader = new LineBufferedReader(stream, true))