Add FontAwesome fixed width (#1737)

* Add FA-FW

* remove braces (ask of kizer)

* reuse iconfont glyphs

* use FAFS for initial font

---------

Co-authored-by: rootdarkarchon <root.darkarchon@outlook.com>
This commit is contained in:
rootdarkarchon 2024-04-14 23:19:27 +02:00 committed by GitHub
parent b8802f0609
commit e97d95dba8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 87 additions and 11 deletions

View file

@ -25,10 +25,15 @@ using Dalamud.Interface.Utility;
using Dalamud.Interface.Windowing;
using Dalamud.Utility;
using Dalamud.Utility.Timing;
using ImGuiNET;
using ImGuiScene;
using PInvoke;
using Serilog;
using SharpDX;
using SharpDX.Direct3D;
using SharpDX.Direct3D11;
@ -131,6 +136,13 @@ internal class InterfaceManager : IInternalDisposableService
public static ImFontPtr IconFont =>
WhenFontsReady().IconFontHandle!.LockUntilPostFrame().OrElse(ImGui.GetIO().FontDefault);
/// <summary>
/// Gets an included FontAwesome icon font with fixed width.
/// <strong>Accessing this static property outside of the main thread is dangerous and not supported.</strong>
/// </summary>
public static ImFontPtr IconFontFixedWidth =>
WhenFontsReady().IconFontFixedWidthHandle!.LockUntilPostFrame().OrElse(ImGui.GetIO().FontDefault);
/// <summary>
/// Gets an included monospaced font.<br />
/// <strong>Accessing this static property outside of the main thread is dangerous and not supported.</strong>
@ -148,6 +160,11 @@ internal class InterfaceManager : IInternalDisposableService
/// </summary>
public FontHandle? IconFontHandle { get; private set; }
/// <summary>
/// Gets the icon font handle with fixed width.
/// </summary>
public FontHandle? IconFontFixedWidthHandle { get; private set; }
/// <summary>
/// Gets the mono font handle.
/// </summary>
@ -732,6 +749,13 @@ internal class InterfaceManager : IInternalDisposableService
GlyphMinAdvanceX = DefaultFontSizePx,
GlyphMaxAdvanceX = DefaultFontSizePx,
})));
this.IconFontFixedWidthHandle = (FontHandle)this.dalamudAtlas.NewDelegateFontHandle(
e => e.OnPreBuild(tk => tk.AddDalamudAssetFont(
DalamudAsset.FontAwesomeFreeSolid,
new()
{
GlyphRanges = new ushort[] { 0x20 },
})));
this.MonoFontHandle = (FontHandle)this.dalamudAtlas.NewDelegateFontHandle(
e => e.OnPreBuild(
tk => tk.AddDalamudAssetFont(
@ -748,6 +772,13 @@ internal class InterfaceManager : IInternalDisposableService
tk.GetFont(this.DefaultFontHandle),
tk.GetFont(this.MonoFontHandle),
missingOnly: true);
// Fill missing glyphs in IconFontFixedWidth with IconFont and fit ratio
tk.CopyGlyphsAcrossFonts(
tk.GetFont(this.IconFontHandle),
tk.GetFont(this.IconFontFixedWidthHandle),
missingOnly: true);
tk.FitRatio(tk.GetFont(this.IconFontFixedWidthHandle));
});
this.DefaultFontHandle.ImFontChanged += (_, font) =>
{

View file

@ -1,4 +1,4 @@
using Dalamud.Interface.Internal;
using Dalamud.Interface.Internal;
using Dalamud.Utility;
using ImGuiNET;
@ -27,6 +27,13 @@ public interface IFontAtlasBuildToolkitPostBuild : IFontAtlasBuildToolkit
/// <returns>The texture index.</returns>
int StoreTexture(IDalamudTextureWrap textureWrap, bool disposeOnError);
/// <summary>
/// Fits a font to a fixed 1:1 ratio adjusting glyph positions horizontally and vertically to fit within font size boundaries.
/// </summary>
/// <param name="font">The font to fit.</param>
/// <param name="rebuildLookupTable">Whether to call target.BuildLookupTable().</param>
void FitRatio(ImFontPtr font, bool rebuildLookupTable = true);
/// <summary>
/// Copies glyphs across fonts, in a safer way.<br />
/// If the font does not belong to the current atlas, this function is a no-op.

View file

@ -1,4 +1,4 @@
using System.Buffers;
using System.Buffers;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
@ -391,12 +391,10 @@ internal sealed partial class FontAtlasFactory
});
case DalamudAsset.LodestoneGameSymbol when !this.factory.HasGameSymbolsFontFile:
{
return this.AddGameGlyphs(
new(GameFontFamily.Axis, fontConfig.SizePx),
fontConfig.GlyphRanges,
fontConfig.MergeFont);
}
default:
return this.factory.AddFont(
@ -858,5 +856,30 @@ internal sealed partial class FontAtlasFactory
}
}
}
/// <inheritdoc/>
public void FitRatio(ImFontPtr font, bool rebuildLookupTable = true)
{
var nsize = font.FontSize;
var glyphs = font.GlyphsWrapped();
foreach (ref var glyph in glyphs.DataSpan)
{
var ratio = 1f;
if (glyph.X1 - glyph.X0 > nsize)
ratio = Math.Max(ratio, (glyph.X1 - glyph.X0) / nsize);
if (glyph.Y1 - glyph.Y0 > nsize)
ratio = Math.Max(ratio, (glyph.Y1 - glyph.Y0) / nsize);
var w = MathF.Round((glyph.X1 - glyph.X0) / ratio, MidpointRounding.ToZero);
var h = MathF.Round((glyph.Y1 - glyph.Y0) / ratio, MidpointRounding.AwayFromZero);
glyph.X0 = MathF.Round((nsize - w) / 2f, MidpointRounding.ToZero);
glyph.Y0 = MathF.Round((nsize - h) / 2f, MidpointRounding.AwayFromZero);
glyph.X1 = glyph.X0 + w;
glyph.Y1 = glyph.Y0 + h;
glyph.AdvanceX = nsize;
}
if (rebuildLookupTable)
this.BuildLookupTable(font);
}
}
}

View file

@ -21,9 +21,13 @@ using Dalamud.Plugin;
using Dalamud.Plugin.Internal.Types;
using Dalamud.Plugin.Services;
using Dalamud.Utility;
using ImGuiNET;
using ImGuiScene;
using Serilog;
using SharpDX.Direct3D11;
namespace Dalamud.Interface;
@ -53,6 +57,7 @@ public sealed class UiBuilder : IDisposable
private IFontHandle? defaultFontHandle;
private IFontHandle? iconFontHandle;
private IFontHandle? monoFontHandle;
private IFontHandle? iconFontFixedWidthHandle;
/// <summary>
/// Initializes a new instance of the <see cref="UiBuilder"/> class and registers it.
@ -251,6 +256,16 @@ public sealed class UiBuilder : IDisposable
this.InterfaceManagerWithScene?.IconFontHandle
?? throw new InvalidOperationException("Scene is not yet ready.")));
/// <summary>
/// Gets the default Dalamud icon font based on FontAwesome 5 free solid with a fixed width and vertically centered glyphs.
/// </summary>
public IFontHandle IconFontFixedWidthHandle =>
this.iconFontFixedWidthHandle ??=
this.scopedFinalizer.Add(
new FontHandleWrapper(
this.InterfaceManagerWithScene?.IconFontFixedWidthHandle
?? throw new InvalidOperationException("Scene is not yet ready.")));
/// <summary>
/// Gets the default Dalamud monospaced font based on Inconsolata Regular.
/// </summary>