mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 15:43:22 +08:00
Update Legacy components to not require skin in ctor
This commit is contained in:
parent
b54eb56169
commit
004798d61d
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
explosion = new LegacyRollingCounter(skin, LegacyFont.Combo)
|
explosion = new LegacyRollingCounter(LegacyFont.Combo)
|
||||||
{
|
{
|
||||||
Alpha = 0.65f,
|
Alpha = 0.65f,
|
||||||
Blending = BlendingParameters.Additive,
|
Blending = BlendingParameters.Additive,
|
||||||
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Scale = new Vector2(1.5f),
|
Scale = new Vector2(1.5f),
|
||||||
},
|
},
|
||||||
counter = new LegacyRollingCounter(skin, LegacyFont.Combo)
|
counter = new LegacyRollingCounter(LegacyFont.Combo)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
Scale = new Vector2(SPRITE_SCALE),
|
Scale = new Vector2(SPRITE_SCALE),
|
||||||
Y = SPINNER_TOP_OFFSET + 115,
|
Y = SPINNER_TOP_OFFSET + 115,
|
||||||
},
|
},
|
||||||
bonusCounter = new LegacySpriteText(source, LegacyFont.Score)
|
bonusCounter = new LegacySpriteText(LegacyFont.Score)
|
||||||
{
|
{
|
||||||
Alpha = 0f,
|
Alpha = 0f,
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
Scale = new Vector2(SPRITE_SCALE),
|
Scale = new Vector2(SPRITE_SCALE),
|
||||||
Position = new Vector2(-87, 445 + spm_hide_offset),
|
Position = new Vector2(-87, 445 + spm_hide_offset),
|
||||||
},
|
},
|
||||||
spmCounter = new LegacySpriteText(source, LegacyFont.Score)
|
spmCounter = new LegacySpriteText(LegacyFont.Score)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
|
@ -100,7 +100,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
if (!this.HasFont(LegacyFont.HitCircle))
|
if (!this.HasFont(LegacyFont.HitCircle))
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new LegacySpriteText(Source, LegacyFont.HitCircle)
|
return new LegacySpriteText(LegacyFont.HitCircle)
|
||||||
{
|
{
|
||||||
// stable applies a blanket 0.8x scale to hitcircle fonts
|
// stable applies a blanket 0.8x scale to hitcircle fonts
|
||||||
Scale = new Vector2(0.8f),
|
Scale = new Vector2(0.8f),
|
||||||
|
@ -2,10 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Skinning.Editor;
|
using osu.Game.Skinning.Editor;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
@ -14,12 +16,22 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
private SkinEditor skinEditor;
|
private SkinEditor skinEditor;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private SkinManager skinManager { get; set; }
|
||||||
|
|
||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public override void SetUpSteps()
|
public override void SetUpSteps()
|
||||||
{
|
{
|
||||||
|
AddStep("set empty legacy skin", () =>
|
||||||
|
{
|
||||||
|
var imported = skinManager.Import(new SkinInfo { Name = "test skin" }).Result;
|
||||||
|
|
||||||
|
skinManager.CurrentSkinInfo.Value = imported;
|
||||||
|
});
|
||||||
|
|
||||||
base.SetUpSteps();
|
base.SetUpSteps();
|
||||||
|
|
||||||
AddStep("add editor overlay", () =>
|
AddStep("reload skin editor", () =>
|
||||||
{
|
{
|
||||||
skinEditor?.Expire();
|
skinEditor?.Expire();
|
||||||
Player.ScaleTo(SkinEditorOverlay.VISIBLE_TARGET_SCALE);
|
Player.ScaleTo(SkinEditorOverlay.VISIBLE_TARGET_SCALE);
|
||||||
|
@ -84,13 +84,13 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
{
|
{
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
popOutCount = new LegacySpriteText(skin, LegacyFont.Combo)
|
popOutCount = new LegacySpriteText(LegacyFont.Combo)
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Margin = new MarginPadding(0.05f),
|
Margin = new MarginPadding(0.05f),
|
||||||
Blending = BlendingParameters.Additive,
|
Blending = BlendingParameters.Additive,
|
||||||
},
|
},
|
||||||
displayedCountSpriteText = new LegacySpriteText(skin, LegacyFont.Combo)
|
displayedCountSpriteText = new LegacySpriteText(LegacyFont.Combo)
|
||||||
{
|
{
|
||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,17 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Screens.Play.HUD
|
namespace osu.Game.Screens.Play.HUD
|
||||||
{
|
{
|
||||||
public class SkinnableElementTargetContainer : SkinReloadableDrawable, ISkinnableTarget
|
public class SkinnableElementTargetContainer : SkinReloadableDrawable, ISkinnableTarget
|
||||||
{
|
{
|
||||||
|
private SkinnableTargetWrapper content;
|
||||||
|
|
||||||
public SkinnableTarget Target { get; }
|
public SkinnableTarget Target { get; }
|
||||||
|
|
||||||
public SkinnableElementTargetContainer(SkinnableTarget target)
|
public SkinnableElementTargetContainer(SkinnableTarget target)
|
||||||
@ -14,15 +19,19 @@ namespace osu.Game.Screens.Play.HUD
|
|||||||
Target = target;
|
Target = target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IEnumerable<SkinnableInfo> CreateSerialisedChildren() =>
|
||||||
|
content.Select(d => d.CreateSerialisedInformation());
|
||||||
|
|
||||||
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
protected override void SkinChanged(ISkinSource skin, bool allowFallback)
|
||||||
{
|
{
|
||||||
base.SkinChanged(skin, allowFallback);
|
base.SkinChanged(skin, allowFallback);
|
||||||
|
|
||||||
var loadable = skin.GetDrawableComponent(new SkinnableTargetComponent(Target));
|
content = skin.GetDrawableComponent(new SkinnableTargetComponent(Target)) as SkinnableTargetWrapper;
|
||||||
|
|
||||||
ClearInternal();
|
ClearInternal();
|
||||||
if (loadable != null)
|
|
||||||
LoadComponentAsync(loadable, AddInternal);
|
if (content != null)
|
||||||
|
LoadComponentAsync(content, AddInternal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,23 +12,22 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableComponent
|
public class LegacyAccuracyCounter : GameplayAccuracyCounter, ISkinnableComponent
|
||||||
{
|
{
|
||||||
private readonly ISkin skin;
|
[Resolved]
|
||||||
|
private ISkinSource skin { get; set; }
|
||||||
|
|
||||||
public LegacyAccuracyCounter(ISkin skin)
|
public LegacyAccuracyCounter()
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight;
|
Anchor = Anchor.TopRight;
|
||||||
Origin = Anchor.TopRight;
|
Origin = Anchor.TopRight;
|
||||||
|
|
||||||
Scale = new Vector2(0.6f);
|
Scale = new Vector2(0.6f);
|
||||||
Margin = new MarginPadding(10);
|
Margin = new MarginPadding(10);
|
||||||
|
|
||||||
this.skin = skin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Resolved(canBeNull: true)]
|
[Resolved(canBeNull: true)]
|
||||||
private HUDOverlay hud { get; set; }
|
private HUDOverlay hud { get; set; }
|
||||||
|
|
||||||
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, LegacyFont.Score)
|
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
@ -38,7 +37,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
if (hud?.ScoreCounter.Drawable is LegacyScoreCounter score)
|
if (hud?.ScoreCounter?.Drawable is LegacyScoreCounter score)
|
||||||
{
|
{
|
||||||
// for now align with the score counter. eventually this will be user customisable.
|
// for now align with the score counter. eventually this will be user customisable.
|
||||||
Y = Parent.ToLocalSpace(score.ScreenSpaceDrawQuad.BottomRight).Y;
|
Y = Parent.ToLocalSpace(score.ScreenSpaceDrawQuad.BottomRight).Y;
|
||||||
|
@ -20,7 +20,9 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
private const double epic_cutoff = 0.5;
|
private const double epic_cutoff = 0.5;
|
||||||
|
|
||||||
private readonly Skin skin;
|
[Resolved]
|
||||||
|
private ISkinSource skin { get; set; }
|
||||||
|
|
||||||
private LegacyHealthPiece fill;
|
private LegacyHealthPiece fill;
|
||||||
private LegacyHealthPiece marker;
|
private LegacyHealthPiece marker;
|
||||||
|
|
||||||
@ -28,11 +30,6 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private bool isNewStyle;
|
private bool isNewStyle;
|
||||||
|
|
||||||
public LegacyHealthDisplay(Skin skin)
|
|
||||||
{
|
|
||||||
this.skin = skin;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
@ -79,7 +76,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
protected override void Flash(JudgementResult result) => marker.Flash(result);
|
protected override void Flash(JudgementResult result) => marker.Flash(result);
|
||||||
|
|
||||||
private static Texture getTexture(Skin skin, string name) => skin.GetTexture($"scorebar-{name}");
|
private static Texture getTexture(ISkinSource skin, string name) => skin.GetTexture($"scorebar-{name}");
|
||||||
|
|
||||||
private static Color4 getFillColour(double hp)
|
private static Color4 getFillColour(double hp)
|
||||||
{
|
{
|
||||||
@ -98,7 +95,7 @@ namespace osu.Game.Skinning
|
|||||||
private readonly Texture dangerTexture;
|
private readonly Texture dangerTexture;
|
||||||
private readonly Texture superDangerTexture;
|
private readonly Texture superDangerTexture;
|
||||||
|
|
||||||
public LegacyOldStyleMarker(Skin skin)
|
public LegacyOldStyleMarker(ISkinSource skin)
|
||||||
{
|
{
|
||||||
normalTexture = getTexture(skin, "ki");
|
normalTexture = getTexture(skin, "ki");
|
||||||
dangerTexture = getTexture(skin, "kidanger");
|
dangerTexture = getTexture(skin, "kidanger");
|
||||||
@ -129,9 +126,9 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
public class LegacyNewStyleMarker : LegacyMarker
|
public class LegacyNewStyleMarker : LegacyMarker
|
||||||
{
|
{
|
||||||
private readonly Skin skin;
|
private readonly ISkinSource skin;
|
||||||
|
|
||||||
public LegacyNewStyleMarker(Skin skin)
|
public LegacyNewStyleMarker(ISkinSource skin)
|
||||||
{
|
{
|
||||||
this.skin = skin;
|
this.skin = skin;
|
||||||
}
|
}
|
||||||
@ -153,7 +150,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
internal class LegacyOldStyleFill : LegacyHealthPiece
|
internal class LegacyOldStyleFill : LegacyHealthPiece
|
||||||
{
|
{
|
||||||
public LegacyOldStyleFill(Skin skin)
|
public LegacyOldStyleFill(ISkinSource skin)
|
||||||
{
|
{
|
||||||
// required for sizing correctly..
|
// required for sizing correctly..
|
||||||
var firstFrame = getTexture(skin, "colour-0");
|
var firstFrame = getTexture(skin, "colour-0");
|
||||||
@ -176,7 +173,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
internal class LegacyNewStyleFill : LegacyHealthPiece
|
internal class LegacyNewStyleFill : LegacyHealthPiece
|
||||||
{
|
{
|
||||||
public LegacyNewStyleFill(Skin skin)
|
public LegacyNewStyleFill(ISkinSource skin)
|
||||||
{
|
{
|
||||||
InternalChild = new Sprite
|
InternalChild = new Sprite
|
||||||
{
|
{
|
||||||
|
@ -12,7 +12,6 @@ namespace osu.Game.Skinning
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class LegacyRollingCounter : RollingCounter<int>
|
public class LegacyRollingCounter : RollingCounter<int>
|
||||||
{
|
{
|
||||||
private readonly ISkin skin;
|
|
||||||
private readonly LegacyFont font;
|
private readonly LegacyFont font;
|
||||||
|
|
||||||
protected override bool IsRollingProportional => true;
|
protected override bool IsRollingProportional => true;
|
||||||
@ -20,11 +19,9 @@ namespace osu.Game.Skinning
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates a new <see cref="LegacyRollingCounter"/>.
|
/// Creates a new <see cref="LegacyRollingCounter"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="skin">The <see cref="ISkin"/> from which to get counter number sprites.</param>
|
|
||||||
/// <param name="font">The legacy font to use for the counter.</param>
|
/// <param name="font">The legacy font to use for the counter.</param>
|
||||||
public LegacyRollingCounter(ISkin skin, LegacyFont font)
|
public LegacyRollingCounter(LegacyFont font)
|
||||||
{
|
{
|
||||||
this.skin = skin;
|
|
||||||
this.font = font;
|
this.font = font;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,6 +30,6 @@ namespace osu.Game.Skinning
|
|||||||
return Math.Abs(newValue - currentValue) * 75.0;
|
return Math.Abs(newValue - currentValue) * 75.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, font);
|
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(font);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
@ -10,24 +11,23 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
public class LegacyScoreCounter : GameplayScoreCounter, ISkinnableComponent
|
public class LegacyScoreCounter : GameplayScoreCounter, ISkinnableComponent
|
||||||
{
|
{
|
||||||
private readonly ISkin skin;
|
|
||||||
|
|
||||||
protected override double RollingDuration => 1000;
|
protected override double RollingDuration => 1000;
|
||||||
protected override Easing RollingEasing => Easing.Out;
|
protected override Easing RollingEasing => Easing.Out;
|
||||||
|
|
||||||
public LegacyScoreCounter(ISkin skin)
|
[Resolved]
|
||||||
|
private ISkinSource skin { get; set; }
|
||||||
|
|
||||||
|
public LegacyScoreCounter()
|
||||||
: base(6)
|
: base(6)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight;
|
Anchor = Anchor.TopRight;
|
||||||
Origin = Anchor.TopRight;
|
Origin = Anchor.TopRight;
|
||||||
|
|
||||||
this.skin = skin;
|
|
||||||
|
|
||||||
Scale = new Vector2(0.96f);
|
Scale = new Vector2(0.96f);
|
||||||
Margin = new MarginPadding(10);
|
Margin = new MarginPadding(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(skin, LegacyFont.Score)
|
protected sealed override OsuSpriteText CreateSpriteText() => new LegacySpriteText(LegacyFont.Score)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
|
@ -334,13 +334,13 @@ namespace osu.Game.Skinning
|
|||||||
return new LegacyComboCounter();
|
return new LegacyComboCounter();
|
||||||
|
|
||||||
case HUDSkinComponents.ScoreCounter:
|
case HUDSkinComponents.ScoreCounter:
|
||||||
return new LegacyScoreCounter(this);
|
return new LegacyScoreCounter();
|
||||||
|
|
||||||
case HUDSkinComponents.AccuracyCounter:
|
case HUDSkinComponents.AccuracyCounter:
|
||||||
return new LegacyAccuracyCounter(this);
|
return new LegacyAccuracyCounter();
|
||||||
|
|
||||||
case HUDSkinComponents.HealthDisplay:
|
case HUDSkinComponents.HealthDisplay:
|
||||||
return new LegacyHealthDisplay(this);
|
return new LegacyHealthDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Text;
|
using osu.Framework.Text;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -9,19 +10,26 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Skinning
|
namespace osu.Game.Skinning
|
||||||
{
|
{
|
||||||
public class LegacySpriteText : OsuSpriteText
|
public sealed class LegacySpriteText : OsuSpriteText
|
||||||
{
|
{
|
||||||
private readonly LegacyGlyphStore glyphStore;
|
private readonly LegacyFont font;
|
||||||
|
|
||||||
|
private LegacyGlyphStore glyphStore;
|
||||||
|
|
||||||
protected override char FixedWidthReferenceCharacter => '5';
|
protected override char FixedWidthReferenceCharacter => '5';
|
||||||
|
|
||||||
protected override char[] FixedWidthExcludeCharacters => new[] { ',', '.', '%', 'x' };
|
protected override char[] FixedWidthExcludeCharacters => new[] { ',', '.', '%', 'x' };
|
||||||
|
|
||||||
public LegacySpriteText(ISkin skin, LegacyFont font)
|
public LegacySpriteText(LegacyFont font)
|
||||||
{
|
{
|
||||||
|
this.font = font;
|
||||||
Shadow = false;
|
Shadow = false;
|
||||||
UseFullGlyphHeight = false;
|
UseFullGlyphHeight = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(ISkinSource skin)
|
||||||
|
{
|
||||||
Font = new FontUsage(skin.GetFontPrefix(font), 1, fixedWidth: true);
|
Font = new FontUsage(skin.GetFontPrefix(font), 1, fixedWidth: true);
|
||||||
Spacing = new Vector2(-skin.GetFontOverlap(font), 0);
|
Spacing = new Vector2(-skin.GetFontOverlap(font), 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user