Skip to content

Commit

Permalink
🚧Improve font loader (KinsonDigital#753)
Browse files Browse the repository at this point in the history
* Start work for issue KinsonDigital#752

* chore: set the graphics extensions methods class to internal

* refactor!: change the name of the FontLoader.Load() parameter

* refactor!: change the name of the FontLoader.Load() parameter

* feat: create new load font methods

* chore: refactor scenes to use new load method extension methods

* cleanup: remove unused using
  • Loading branch information
CalvinWilkinson committed Oct 5, 2023
1 parent 3d1baa3 commit d304095
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 20 deletions.
7 changes: 5 additions & 2 deletions Testing/VelaptorTesting/Scenes/LayeredTextRenderingScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace VelaptorTesting.Scenes;
using Velaptor;
using Velaptor.Content;
using Velaptor.Content.Fonts;
using Velaptor.ExtensionMethods;
using Velaptor.Factories;
using Velaptor.Graphics.Renderers;
using Velaptor.Input;
Expand Down Expand Up @@ -63,7 +64,8 @@ public override void LoadContent()
this.background = ContentLoader.LoadTexture("layered-rendering-background");
this.backgroundPos = new Vector2(WindowCenter.X, WindowCenter.Y);

this.font = ContentLoader.LoadFont(DefaultFont, 12);
var fontLoader = new FontLoader();
this.font = fontLoader.Load(DefaultFont, 12);
this.font.Style = FontStyle.Bold;
this.font.Size = 24;

Expand Down Expand Up @@ -207,12 +209,13 @@ private void UpdateWhiteBoxLayer()
{
if (this.currentKeyState.IsKeyDown(KeyCode.L) && this.prevKeyState.IsKeyUp(KeyCode.L))
{
var paramName = $"this.{nameof(this.whiteLayer)}";
this.whiteLayer = this.whiteLayer switch
{
RenderLayer.One => RenderLayer.Three,
RenderLayer.Three => RenderLayer.Five,
RenderLayer.Five => RenderLayer.One,
_ => throw new ArgumentOutOfRangeException()
_ => throw new ArgumentOutOfRangeException(paramName, this.whiteLayer, "Invalid enum value.")
};
}
}
Expand Down
5 changes: 3 additions & 2 deletions Testing/VelaptorTesting/Scenes/TextRenderingScene.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ namespace VelaptorTesting.Scenes;
using System.Numerics;
using Velaptor;
using Velaptor.Content.Fonts;
using Velaptor.ExtensionMethods;
using Velaptor.Factories;
using Velaptor.Graphics.Renderers;
using Velaptor.Scene;
Expand Down Expand Up @@ -62,10 +63,10 @@ public override void LoadContent()
this.backgroundManager.Load(new Vector2(WindowCenter.X, WindowCenter.Y));

var renderFactory = new RendererFactory();

this.fontRenderer = renderFactory.CreateFontRenderer();

this.textFont = ContentLoader.LoadFont(DefaultRegularFont, 12);
var fontLoader = ContentLoaderFactory.CreateFontLoader();
this.textFont = fontLoader.Load(DefaultRegularFont, 12);

// Rotate CW Button
this.btnRotateCW = new Button
Expand Down
2 changes: 1 addition & 1 deletion Testing/VelaptorTests/Content/Fonts/FontLoaderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ public void Load_WithNullOrEmptyParam_ThrowsException(string contentName)

// Assert
act.Should().Throw<ArgumentNullException>()
.WithMessage("The parameter must not be null. (Parameter 'contentWithMetaData')");
.WithMessage("The parameter must not be null. (Parameter 'contentPathOrName')");
}

[Fact]
Expand Down
37 changes: 37 additions & 0 deletions Testing/VelaptorTests/ExtensionMethods/ContentExtensionsTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// <copyright file="ContentExtensionsTests.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

namespace VelaptorTests.ExtensionMethods;

using NSubstitute;
using Velaptor.Content;
using Velaptor.Content.Fonts;
using Velaptor.ExtensionMethods;
using Xunit;

/// <summary>
/// Tests the <see cref="ContentExtensions"/> clas.
/// </summary>
public class ContentExtensionsTests
{
#region Method Tests
[Theory]
[InlineData("test-font", 12, "test-font.ttf|size:12")]
[InlineData("test-font.ttf", 14, "test-font.ttf|size:14")]
[InlineData("test-font.invalid-extension", 16, "test-font.ttf|size:16")]
public void Load_WhenInvokingILoaderOfTypeIFont_LoadsFont(string fontName, uint size, string expected)
{
// Arrange
var mockFont = Substitute.For<IFont>();
var mockFontLoader = Substitute.For<ILoader<IFont>>();
mockFontLoader.Load(Arg.Any<string>()).Returns(mockFont);

// Act
mockFontLoader.Load(fontName, size);

// Assert
mockFontLoader.Received(1).Load(expected);
}
#endregion
}
1 change: 0 additions & 1 deletion Testing/VelaptorTests/Graphics/RectShapeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace VelaptorTests.Graphics;
using System.Drawing;
using System.Numerics;
using FluentAssertions;
using Helpers;
using Velaptor.Graphics;
using Xunit;

Expand Down
22 changes: 11 additions & 11 deletions Velaptor/Content/Fonts/FontLoader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// <copyright file="FontLoader.cs" company="KinsonDigital">
// <copyright file="FontLoader.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

Expand Down Expand Up @@ -126,10 +126,10 @@ internal FontLoader(
/// <summary>
/// Loads font content from the application's content directory or directly using a full file path.
/// </summary>
/// <param name="contentWithMetaData">The name or full file path to the font with metadata.</param>
/// <param name="contentPathOrName">The name or full file path to the font with metadata.</param>
/// <returns>The loaded font.</returns>
/// <exception cref="ArgumentNullException">
/// Occurs when the <paramref name="contentWithMetaData"/> argument is null or empty.
/// Occurs when the <paramref name="contentPathOrName"/> argument is null or empty.
/// </exception>
/// <exception cref="CachingMetaDataException">
/// Occurs if the metadata is missing or invalid.
Expand All @@ -155,14 +155,14 @@ internal FontLoader(
/// ContentLoader.Load("my-font|size:12");
/// </code>
/// </example>
public IFont Load(string contentWithMetaData)
public IFont Load(string contentPathOrName)
{
if (string.IsNullOrEmpty(contentWithMetaData))
if (string.IsNullOrEmpty(contentPathOrName))
{
throw new ArgumentNullException(nameof(contentWithMetaData), "The parameter must not be null.");
throw new ArgumentNullException(nameof(contentPathOrName), "The parameter must not be null.");
}

var parseResult = this.fontMetaDataParser.Parse(contentWithMetaData);
var parseResult = this.fontMetaDataParser.Parse(contentPathOrName);
string fullFontFilePath;

if (parseResult.ContainsMetaData)
Expand All @@ -188,7 +188,7 @@ public IFont Load(string contentWithMetaData)
}
else
{
var exceptionMsg = $"The metadata '{parseResult.MetaData}' is invalid when loading '{contentWithMetaData}'.";
var exceptionMsg = $"The metadata '{parseResult.MetaData}' is invalid when loading '{contentPathOrName}'.";
exceptionMsg += $"{Environment.NewLine}\tExpected MetaData Syntax: {ExpectedMetaDataSyntax}";
exceptionMsg += $"{Environment.NewLine}\tExample: size:12";
throw new CachingMetaDataException(exceptionMsg);
Expand Down Expand Up @@ -234,9 +234,9 @@ public IFont Load(string contentWithMetaData)
}

/// <inheritdoc/>
public void Unload(string contentWithMetaData)
public void Unload(string contentPathOrName)
{
var parseResult = this.fontMetaDataParser.Parse(contentWithMetaData);
var parseResult = this.fontMetaDataParser.Parse(contentPathOrName);

if (parseResult.ContainsMetaData)
{
Expand All @@ -252,7 +252,7 @@ public void Unload(string contentWithMetaData)
}
else
{
var exceptionMsg = $"The metadata '{parseResult.MetaData}' is invalid when unloading '{contentWithMetaData}'.";
var exceptionMsg = $"The metadata '{parseResult.MetaData}' is invalid when unloading '{contentPathOrName}'.";
exceptionMsg += $"{Environment.NewLine}\tExpected MetaData Syntax: {ExpectedMetaDataSyntax}";
exceptionMsg += $"{Environment.NewLine}\tExample: size:12";
throw new CachingMetaDataException(exceptionMsg);
Expand Down
72 changes: 72 additions & 0 deletions Velaptor/ExtensionMethods/ContentExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// <copyright file="ContentExtensions.cs" company="KinsonDigital">
// Copyright (c) KinsonDigital. All rights reserved.
// </copyright>

namespace Velaptor.ExtensionMethods;

using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using Content;
using Content.Fonts;

/// <summary>
/// Provides content related extension methods.
/// </summary>
public static class ContentExtensions
{
/// <summary>
/// Loads font content from the application's content directory or directly using a full file path.
/// </summary>
/// <param name="loader">The font loader.</param>
/// <param name="fontName">The name or full file path to the font with metadata.</param>
/// <param name="size">The size of the font.</param>
/// <returns>The loaded font.</returns>
/// <exception cref="ArgumentNullException">
/// Occurs when the <paramref name="fontName"/> argument is null or empty.
/// </exception>
/// <exception cref="FileNotFoundException">
/// Occurs if the font file does not exist.
/// </exception>
/// <remarks>
/// If a path is used, it must be a fully qualified file path.
/// <para>Directory paths are not valid.</para>
/// </remarks>
[ExcludeFromCodeCoverage(Justification = $"Cannot test due to interaction with '{nameof(IoC)}' container.")]
public static IFont Load(this FontLoader loader, string fontName, uint size)
{
ArgumentException.ThrowIfNullOrEmpty(fontName);

fontName = Path.HasExtension(fontName) ? Path.GetFileNameWithoutExtension(fontName) : fontName;
fontName = $"{fontName}.ttf|size:{size}";

return loader.Load(fontName);
}

/// <summary>
/// Loads font content from the application's content directory or directly using a full file path.
/// </summary>
/// <param name="loader">The font loader.</param>
/// <param name="fontName">The name or full file path to the font with metadata.</param>
/// <param name="size">The size of the font.</param>
/// <returns>The loaded font.</returns>
/// <exception cref="ArgumentNullException">
/// Occurs when the <paramref name="fontName"/> argument is null or empty.
/// </exception>
/// <exception cref="FileNotFoundException">
/// Occurs if the font file does not exist.
/// </exception>
/// <remarks>
/// If a path is used, it must be a fully qualified file path.
/// <para>Directory paths are not valid.</para>
/// </remarks>
public static IFont Load(this ILoader<IFont> loader, string fontName, uint size)
{
ArgumentException.ThrowIfNullOrEmpty(fontName);

fontName = Path.HasExtension(fontName) ? Path.GetFileNameWithoutExtension(fontName) : fontName;
fontName = $"{fontName}.ttf|size:{size}";

return loader.Load(fontName);
}
}
6 changes: 3 additions & 3 deletions Velaptor/Graphics/GraphicsExtensionMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ namespace Velaptor.Graphics;
/// <summary>
/// Provides various helper extension methods.
/// </summary>
public static class GraphicsExtensionMethods
internal static class GraphicsExtensionMethods
{
/// <summary>
/// Gets the max height from the list of glyph metrics at the given <paramref name="index"/>.
/// </summary>
/// <param name="value">The list of glyph metric items.</param>
/// <param name="index">The index of the list of glyph metric lists to get the offset from.</param>
/// <returns>The maximum height.</returns>
internal static float MaxHeight(this List<GlyphMetrics[]> value, int index)
public static float MaxHeight(this List<GlyphMetrics[]> value, int index)
=> value[index].Max(i => i.GlyphHeight);

/// <summary>
Expand All @@ -27,7 +27,7 @@ internal static float MaxHeight(this List<GlyphMetrics[]> value, int index)
/// <param name="value">The list of glyph metric items.</param>
/// <param name="index">The index of the list of glyph metric lists to get the offset from.</param>
/// <returns>The maximum vertical offset.</returns>
internal static float MaxVerticalOffset(this List<GlyphMetrics[]> value, int index)
public static float MaxVerticalOffset(this List<GlyphMetrics[]> value, int index)
=> value[index]
.Max(i => i.GlyphHeight - i.HoriBearingY > 0
? i.GlyphHeight - i.HoriBearingY
Expand Down

0 comments on commit d304095

Please sign in to comment.