mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Expose wrapped default font handle
This commit is contained in:
parent
d70b430e0d
commit
967ae97308
4 changed files with 131 additions and 21 deletions
|
|
@ -13,7 +13,6 @@ using Dalamud.Game.ClientState.Keys;
|
|||
using Dalamud.Game.Internal.DXGI;
|
||||
using Dalamud.Hooking;
|
||||
using Dalamud.Hooking.WndProcHook;
|
||||
using Dalamud.Interface.GameFonts;
|
||||
using Dalamud.Interface.Internal.ManagedAsserts;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.ManagedFontAtlas;
|
||||
|
|
@ -87,9 +86,6 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
private Hook<ResizeBuffersDelegate>? resizeBuffersHook;
|
||||
|
||||
private IFontAtlas? dalamudAtlas;
|
||||
private IFontHandle.IInternal? defaultFontHandle;
|
||||
private IFontHandle.IInternal? iconFontHandle;
|
||||
private IFontHandle.IInternal? monoFontHandle;
|
||||
|
||||
// can't access imgui IO before first present call
|
||||
private bool lastWantCapture = false;
|
||||
|
|
@ -131,19 +127,34 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
/// Gets the default ImGui font.<br />
|
||||
/// <strong>Accessing this static property outside of the main thread is dangerous and not supported.</strong>
|
||||
/// </summary>
|
||||
public static ImFontPtr DefaultFont => WhenFontsReady().defaultFontHandle!.ImFont.OrElse(ImGui.GetIO().FontDefault);
|
||||
public static ImFontPtr DefaultFont => WhenFontsReady().DefaultFontHandle!.ImFont.OrElse(ImGui.GetIO().FontDefault);
|
||||
|
||||
/// <summary>
|
||||
/// Gets an included FontAwesome icon font.<br />
|
||||
/// <strong>Accessing this static property outside of the main thread is dangerous and not supported.</strong>
|
||||
/// </summary>
|
||||
public static ImFontPtr IconFont => WhenFontsReady().iconFontHandle!.ImFont.OrElse(ImGui.GetIO().FontDefault);
|
||||
public static ImFontPtr IconFont => WhenFontsReady().IconFontHandle!.ImFont.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>
|
||||
/// </summary>
|
||||
public static ImFontPtr MonoFont => WhenFontsReady().monoFontHandle!.ImFont.OrElse(ImGui.GetIO().FontDefault);
|
||||
public static ImFontPtr MonoFont => WhenFontsReady().MonoFontHandle!.ImFont.OrElse(ImGui.GetIO().FontDefault);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default font handle.
|
||||
/// </summary>
|
||||
public IFontHandle.IInternal? DefaultFontHandle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the icon font handle.
|
||||
/// </summary>
|
||||
public IFontHandle.IInternal? IconFontHandle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mono font handle.
|
||||
/// </summary>
|
||||
public IFontHandle.IInternal? MonoFontHandle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the pointer to ImGui.IO(), when it was last used.
|
||||
|
|
@ -691,9 +702,9 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
.CreateFontAtlas(nameof(InterfaceManager), FontAtlasAutoRebuildMode.Disable);
|
||||
using (this.dalamudAtlas.SuppressAutoRebuild())
|
||||
{
|
||||
this.defaultFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
this.DefaultFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
e => e.OnPreBuild(tk => tk.AddDalamudDefaultFont(DefaultFontSizePx)));
|
||||
this.iconFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
this.IconFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
e => e.OnPreBuild(
|
||||
tk => tk.AddFontAwesomeIconFont(
|
||||
new()
|
||||
|
|
@ -702,7 +713,7 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
GlyphMinAdvanceX = DefaultFontSizePx,
|
||||
GlyphMaxAdvanceX = DefaultFontSizePx,
|
||||
})));
|
||||
this.monoFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
this.MonoFontHandle = (IFontHandle.IInternal)this.dalamudAtlas.NewDelegateFontHandle(
|
||||
e => e.OnPreBuild(
|
||||
tk => tk.AddDalamudAssetFont(
|
||||
DalamudAsset.InconsolataRegular,
|
||||
|
|
@ -715,12 +726,12 @@ internal class InterfaceManager : IDisposable, IServiceType
|
|||
// Use font handles directly.
|
||||
|
||||
// Fill missing glyphs in MonoFont from DefaultFont
|
||||
tk.CopyGlyphsAcrossFonts(this.defaultFontHandle.ImFont, this.monoFontHandle.ImFont, true);
|
||||
tk.CopyGlyphsAcrossFonts(this.DefaultFontHandle.ImFont, this.MonoFontHandle.ImFont, true);
|
||||
|
||||
// Update default font
|
||||
unsafe
|
||||
{
|
||||
ImGui.GetIO().NativePtr->FontDefault = this.defaultFontHandle.ImFont;
|
||||
ImGui.GetIO().NativePtr->FontDefault = this.DefaultFontHandle.ImFont;
|
||||
}
|
||||
|
||||
// Broadcast to auto-rebuilding instances
|
||||
|
|
|
|||
|
|
@ -122,6 +122,10 @@ public interface IFontAtlas : IDisposable
|
|||
/// Note that <see cref="BuildTask"/> would not necessarily get changed from calling this function.
|
||||
/// </summary>
|
||||
/// <exception cref="InvalidOperationException">If <see cref="AutoRebuildMode"/> is <see cref="FontAtlasAutoRebuildMode.Async"/>.</exception>
|
||||
/// <remarks>
|
||||
/// Using this method will block the main thread on rebuilding fonts, effectively calling
|
||||
/// <see cref="BuildFontsImmediately"/> from the main thread. Consider migrating to <see cref="BuildFontsAsync"/>.
|
||||
/// </remarks>
|
||||
void BuildFontsOnNextFrame();
|
||||
|
||||
/// <summary>
|
||||
|
|
|
|||
|
|
@ -12,7 +12,12 @@ namespace Dalamud.Interface.ManagedFontAtlas;
|
|||
public interface IFontHandle : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Called when the built instance of <see cref="ImFontPtr"/> has been changed.
|
||||
/// Called when the built instance of <see cref="ImFontPtr"/> has been changed.<br />
|
||||
/// This event will be invoked on the same thread with
|
||||
/// <see cref="IFontAtlas"/>.<see cref="IFontAtlas.BuildStepChange"/>,
|
||||
/// when the build step is <see cref="FontAtlasBuildStep.PostPromotion"/>.<br />
|
||||
/// See <see cref="IFontAtlas.BuildFontsOnNextFrame"/>, <see cref="IFontAtlas.BuildFontsImmediately"/>, and
|
||||
/// <see cref="IFontAtlas.BuildFontsAsync"/>.
|
||||
/// </summary>
|
||||
event Action<IFontHandle> ImFontChanged;
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,10 @@ public sealed class UiBuilder : IDisposable
|
|||
private bool hasErrorWindow = false;
|
||||
private bool lastFrameUiHideState = false;
|
||||
|
||||
private IFontHandle? defaultFontHandle;
|
||||
private IFontHandle? iconFontHandle;
|
||||
private IFontHandle? monoFontHandle;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UiBuilder"/> class and registers it.
|
||||
/// You do not have to call this manually.
|
||||
|
|
@ -103,7 +107,14 @@ public sealed class UiBuilder : IDisposable
|
|||
/// (at any time), so you should both reload your custom fonts and restore those
|
||||
/// pointers inside this handler.
|
||||
/// </summary>
|
||||
[Obsolete($"Use {nameof(this.FontAtlas)} instead.", false)]
|
||||
/// <remarks>
|
||||
/// To add your custom font, use <see cref="FontAtlas"/>.<see cref="IFontAtlas.NewDelegateFontHandle"/> or
|
||||
/// <see cref="IFontAtlas.NewGameFontHandle"/>.<br />
|
||||
/// To be notified on font changes after fonts are built, use
|
||||
/// <see cref="DefaultFontHandle"/>.<see cref="IFontHandle.ImFontChanged"/>.<br />
|
||||
/// For all other purposes, use <see cref="FontAtlas"/>.<see cref="IFontAtlas.BuildStepChange"/>.
|
||||
/// </remarks>
|
||||
[Obsolete("See remarks.", false)]
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
public event Action? BuildFonts;
|
||||
|
||||
|
|
@ -113,6 +124,13 @@ public sealed class UiBuilder : IDisposable
|
|||
/// (at any time), so you should both reload your custom fonts and restore those
|
||||
/// pointers inside this handler.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// To add your custom font, use <see cref="FontAtlas"/>.<see cref="IFontAtlas.NewDelegateFontHandle"/> or
|
||||
/// <see cref="IFontAtlas.NewGameFontHandle"/>.<br />
|
||||
/// To be notified on font changes after fonts are built, use
|
||||
/// <see cref="DefaultFontHandle"/>.<see cref="IFontHandle.ImFontChanged"/>.<br />
|
||||
/// For all other purposes, use <see cref="FontAtlas"/>.<see cref="IFontAtlas.BuildStepChange"/>.
|
||||
/// </remarks>
|
||||
[Obsolete($"Use {nameof(this.FontAtlas)} instead.", false)]
|
||||
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||
public event Action? AfterBuildFonts;
|
||||
|
|
@ -143,6 +161,23 @@ public sealed class UiBuilder : IDisposable
|
|||
/// Gets the default Dalamud font - supporting all game languages and icons.<br />
|
||||
/// <strong>Accessing this static property outside of <see cref="Draw"/> is dangerous and not supported.</strong>
|
||||
/// </summary>
|
||||
public static ImFontPtr DefaultFont => InterfaceManager.DefaultFont;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default Dalamud icon font based on FontAwesome 5 Free solid.<br />
|
||||
/// <strong>Accessing this static property outside of <see cref="Draw"/> is dangerous and not supported.</strong>
|
||||
/// </summary>
|
||||
public static ImFontPtr IconFont => InterfaceManager.IconFont;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default Dalamud monospaced font based on Inconsolata Regular.<br />
|
||||
/// <strong>Accessing this static property outside of <see cref="Draw"/> is dangerous and not supported.</strong>
|
||||
/// </summary>
|
||||
public static ImFontPtr MonoFont => InterfaceManager.MonoFont;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the handle to the default Dalamud font - supporting all game languages and icons.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A font handle corresponding to this font can be obtained with:
|
||||
/// <code>
|
||||
|
|
@ -151,11 +186,15 @@ public sealed class UiBuilder : IDisposable
|
|||
/// tk => tk.AddDalamudDefaultFont(UiBuilder.DefaultFontSizePt)));
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public static ImFontPtr DefaultFont => InterfaceManager.DefaultFont;
|
||||
public IFontHandle DefaultFontHandle =>
|
||||
this.defaultFontHandle ??=
|
||||
this.scopedFinalizer.Add(
|
||||
new FontHandleWrapper(
|
||||
this.InterfaceManagerWithScene?.DefaultFontHandle
|
||||
?? throw new InvalidOperationException("Scene is not yet ready.")));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default Dalamud icon font based on FontAwesome 5 Free solid.<br />
|
||||
/// <strong>Accessing this static property outside of <see cref="Draw"/> is dangerous and not supported.</strong>
|
||||
/// Gets the default Dalamud icon font based on FontAwesome 5 Free solid.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A font handle corresponding to this font can be obtained with:
|
||||
|
|
@ -165,11 +204,15 @@ public sealed class UiBuilder : IDisposable
|
|||
/// tk => tk.AddFontAwesomeIconFont(new() { SizePt = UiBuilder.DefaultFontSizePt })));
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public static ImFontPtr IconFont => InterfaceManager.IconFont;
|
||||
public IFontHandle IconFontHandle =>
|
||||
this.iconFontHandle ??=
|
||||
this.scopedFinalizer.Add(
|
||||
new FontHandleWrapper(
|
||||
this.InterfaceManagerWithScene?.IconFontHandle
|
||||
?? throw new InvalidOperationException("Scene is not yet ready.")));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the default Dalamud monospaced font based on Inconsolata Regular.<br />
|
||||
/// <strong>Accessing this static property outside of <see cref="Draw"/> is dangerous and not supported.</strong>
|
||||
/// Gets the default Dalamud monospaced font based on Inconsolata Regular.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// A font handle corresponding to this font can be obtained with:
|
||||
|
|
@ -181,7 +224,12 @@ public sealed class UiBuilder : IDisposable
|
|||
/// new() { SizePt = UiBuilder.DefaultFontSizePt })));
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public static ImFontPtr MonoFont => InterfaceManager.MonoFont;
|
||||
public IFontHandle MonoFontHandle =>
|
||||
this.monoFontHandle ??=
|
||||
this.scopedFinalizer.Add(
|
||||
new FontHandleWrapper(
|
||||
this.InterfaceManagerWithScene?.MonoFontHandle
|
||||
?? throw new InvalidOperationException("Scene is not yet ready.")));
|
||||
|
||||
/// <summary>
|
||||
/// Gets the game's active Direct3D device.
|
||||
|
|
@ -660,4 +708,46 @@ public sealed class UiBuilder : IDisposable
|
|||
{
|
||||
this.ResizeBuffers?.InvokeSafely();
|
||||
}
|
||||
|
||||
private class FontHandleWrapper : IFontHandle
|
||||
{
|
||||
private IFontHandle? wrapped;
|
||||
|
||||
public FontHandleWrapper(IFontHandle wrapped)
|
||||
{
|
||||
this.wrapped = wrapped;
|
||||
this.wrapped.ImFontChanged += this.WrappedOnImFontChanged;
|
||||
}
|
||||
|
||||
public event Action<IFontHandle>? ImFontChanged;
|
||||
|
||||
public Exception? LoadException =>
|
||||
this.wrapped!.LoadException ?? new ObjectDisposedException(nameof(FontHandleWrapper));
|
||||
|
||||
public bool Available => this.wrapped?.Available ?? false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (this.wrapped is not { } w)
|
||||
return;
|
||||
|
||||
this.wrapped = null;
|
||||
w.ImFontChanged -= this.WrappedOnImFontChanged;
|
||||
// Note: do not dispose w; we do not own it
|
||||
}
|
||||
|
||||
public IFontHandle.ImFontLocked Lock() =>
|
||||
this.wrapped?.Lock() ?? throw new ObjectDisposedException(nameof(FontHandleWrapper));
|
||||
|
||||
public IFontHandle.FontPopper Push() =>
|
||||
this.wrapped?.Push() ?? throw new ObjectDisposedException(nameof(FontHandleWrapper));
|
||||
|
||||
public Task<IFontHandle> WaitAsync() =>
|
||||
this.wrapped?.WaitAsync().ContinueWith(_ => (IFontHandle)this) ??
|
||||
throw new ObjectDisposedException(nameof(FontHandleWrapper));
|
||||
|
||||
public override string ToString() => $"{nameof(FontHandleWrapper)}({this.wrapped})";
|
||||
|
||||
private void WrappedOnImFontChanged(IFontHandle obj) => this.ImFontChanged.InvokeSafely(this);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue