Merge branch 'apiX' into feature/itextureprovider-updates

This commit is contained in:
Soreepeong 2024-05-12 22:17:32 +09:00
commit 8c7771bf7d
2213 changed files with 10372 additions and 1088868 deletions

View file

@ -132,14 +132,6 @@ internal sealed class DelegateFontHandle : FontHandle
/// <inheritdoc/>
public IFontHandleManager Manager { get; }
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public IFontAtlasBuildToolkitPreBuild? PreBuildToolkitForApi9Compat { get; set; }
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public bool CreateFontOnAccess { get; set; }
/// <inheritdoc/>
public void Dispose()
{

View file

@ -1,9 +1,9 @@
using System.Buffers;
using System.Buffers;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.Unicode;
using Dalamud.Configuration.Internal;
using Dalamud.Interface.FontIdentifier;
@ -34,7 +34,7 @@ internal sealed partial class FontAtlasFactory
/// Implementations for <see cref="IFontAtlasBuildToolkitPreBuild"/> and
/// <see cref="IFontAtlasBuildToolkitPostBuild"/>.
/// </summary>
private class BuildToolkit : IFontAtlasBuildToolkit.IApi9Compat, IFontAtlasBuildToolkitPreBuild, IFontAtlasBuildToolkitPostBuild, IDisposable
private class BuildToolkit : IFontAtlasBuildToolkitPreBuild, IFontAtlasBuildToolkitPostBuild, IDisposable
{
private static readonly ushort FontAwesomeIconMin =
(ushort)Enum.GetValues<FontAwesomeIcon>().Where(x => x > 0).Min();
@ -112,34 +112,6 @@ internal sealed partial class FontAtlasFactory
/// <inheritdoc/>
public void DisposeWithAtlas(Action action) => this.data.Garbage.Add(action);
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public void FromUiBuilderObsoleteEventHandlers(Action action)
{
var previousSubstances = new IFontHandleSubstance[this.data.Substances.Count];
for (var i = 0; i < previousSubstances.Length; i++)
{
previousSubstances[i] = this.data.Substances[i].Manager.Substance;
this.data.Substances[i].Manager.Substance = this.data.Substances[i];
this.data.Substances[i].CreateFontOnAccess = true;
this.data.Substances[i].PreBuildToolkitForApi9Compat = this;
}
try
{
action();
}
finally
{
for (var i = 0; i < previousSubstances.Length; i++)
{
this.data.Substances[i].Manager.Substance = previousSubstances[i];
this.data.Substances[i].CreateFontOnAccess = false;
this.data.Substances[i].PreBuildToolkitForApi9Compat = null;
}
}
}
/// <inheritdoc/>
public ImFontPtr GetFont(IFontHandle fontHandle)
{
@ -167,7 +139,7 @@ internal sealed partial class FontAtlasFactory
/// <inheritdoc/>
public int StoreTexture(IDalamudTextureWrap textureWrap, bool disposeOnError) =>
this.data.AddNewTexture(textureWrap, disposeOnError);
/// <inheritdoc/>
public void RegisterPostBuild(Action action) => this.registeredPostBuildActions.Add(action);
@ -392,12 +364,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(
@ -436,9 +406,163 @@ internal sealed partial class FontAtlasFactory
public ImFontPtr AddGameGlyphs(GameFontStyle gameFontStyle, ushort[]? glyphRanges, ImFontPtr mergeFont) =>
this.gameFontHandleSubstance.AttachGameGlyphs(this, mergeFont, gameFontStyle, glyphRanges);
/// <inheritdoc/>
public void AttachWindowsDefaultFont(
CultureInfo cultureInfo,
in SafeFontConfig fontConfig,
int weight = (int)DWRITE_FONT_WEIGHT.DWRITE_FONT_WEIGHT_NORMAL,
int stretch = (int)DWRITE_FONT_STRETCH.DWRITE_FONT_STRETCH_NORMAL,
int style = (int)DWRITE_FONT_STYLE.DWRITE_FONT_STYLE_NORMAL)
{
var targetFont = fontConfig.MergeFont;
if (targetFont.IsNull())
targetFont = this.Font;
if (targetFont.IsNull())
return;
// https://learn.microsoft.com/en-us/windows/apps/design/globalizing/loc-international-fonts
var splitTag = cultureInfo.IetfLanguageTag.Split("-");
foreach (var test in new[]
{
cultureInfo.IetfLanguageTag,
$"{splitTag[0]}-{splitTag[^1]}",
})
{
var familyName = test switch
{
"af-ZA" => "Segoe UI",
"am-ET" => "Ebrima",
"ar-SA" => "Segoe UI",
"as-IN" => "Nirmala UI",
"az-Latn-AZ" => "Segoe UI",
"be-BY" => "Segoe UI",
"bg-BG" => "Segoe UI",
"bn-BD" => "Nirmala UI",
"bn-IN" => "Nirmala UI",
"bs-Latn-BA" => "Segoe UI",
"ca-ES" => "Segoe UI",
"ca-ES-valencia" => "Segoe UI",
"chr-CHER-US" => "Gadugi",
"cs-CZ" => "Segoe UI",
"cy-GB" => "Segoe UI",
"da-DK" => "Segoe UI",
"de-DE" => "Segoe UI",
"el-GR" => "Segoe UI",
"en-GB" => "Segoe UI",
"es-ES" => "Segoe UI",
"et-EE" => "Segoe UI",
"eu-ES" => "Segoe UI",
"fa-IR" => "Segoe UI",
"fi-FI" => "Segoe UI",
"fil-PH" => "Segoe UI",
"fr-FR" => "Segoe UI",
"ga-IE" => "Segoe UI",
"gd-GB" => "Segoe UI",
"gl-ES" => "Segoe UI",
"gu-IN" => "Nirmala UI",
"ha-Latn-NG" => "Segoe UI",
"he-IL" => "Segoe UI",
"hi-IN" => "Nirmala UI",
"hr-HR" => "Segoe UI",
"hu-HU" => "Segoe UI",
"hy-AM" => "Segoe UI",
"id-ID" => "Segoe UI",
"ig-NG" => "Segoe UI",
"is-IS" => "Segoe UI",
"it-IT" => "Segoe UI",
"ja-JP" => "Yu Gothic UI",
"ka-GE" => "Segoe UI",
"kk-KZ" => "Segoe UI",
"km-KH" => "Leelawadee UI",
"kn-IN" => "Nirmala UI",
"ko-KR" => "Malgun Gothic",
"kok-IN" => "Nirmala UI",
"ku-ARAB-IQ" => "Segoe UI",
"ky-KG" => "Segoe UI",
"lb-LU" => "Segoe UI",
"lt-LT" => "Segoe UI",
"lv-LV" => "Segoe UI",
"mi-NZ" => "Segoe UI",
"mk-MK" => "Segoe UI",
"ml-IN" => "Nirmala UI",
"mn-MN" => "Segoe UI",
"mr-IN" => "Nirmala UI",
"ms-MY" => "Segoe UI",
"mt-MT" => "Segoe UI",
"nb-NO" => "Segoe UI",
"ne-NP" => "Nirmala UI",
"nl-NL" => "Segoe UI",
"nn-NO" => "Segoe UI",
"nso-ZA" => "Segoe UI",
"or-IN" => "Nirmala UI",
"pa-Arab-PK" => "Segoe UI",
"pa-IN" => "Nirmala UI",
"pl-PL" => "Segoe UI",
"prs-AF" => "Segoe UI",
"pt-BR" => "Segoe UI",
"pt-PT" => "Segoe UI",
"qut-GT" => "Segoe UI",
"quz-PE" => "Segoe UI",
"ro-RO" => "Segoe UI",
"ru-RU" => "Segoe UI",
"rw-RW" => "Segoe UI",
"sd-Arab-PK" => "Segoe UI",
"si-LK" => "Nirmala UI",
"sk-SK" => "Segoe UI",
"sl-SI" => "Segoe UI",
"sq-AL" => "Segoe UI",
"sr-Cyrl-BA" => "Segoe UI",
"sr-Cyrl-CS" => "Segoe UI",
"sr-Latn-CS" => "Segoe UI",
"sv-SE" => "Segoe UI",
"sw-KE" => "Segoe UI",
"ta-IN" => "Nirmala UI",
"te-IN" => "Nirmala UI",
"tg-Cyrl-TJ" => "Segoe UI",
"th-TH" => "Leelawadee UI",
"ti-ET" => "Ebrima",
"tk-TM" => "Segoe UI",
"tn-ZA" => "Segoe UI",
"tr-TR" => "Segoe UI",
"tt-RU" => "Segoe UI",
"ug-CN" => "Segoe UI",
"uk-UA" => "Segoe UI",
"ur-PK" => "Segoe UI",
"uz-Latn-UZ" => "Segoe UI",
"vi-VN" => "Segoe UI",
"wo-SN" => "Segoe UI",
"xh-ZA" => "Segoe UI",
"yo-NG" => "Segoe UI",
"zh-CN" => "Microsoft YaHei UI",
"zh-HK" => "Microsoft JhengHei UI",
"zh-TW" => "Microsoft JhengHei UI",
"zh-Hans" => "Microsoft YaHei UI",
"zh-Hant" => "Microsoft YaHei UI",
"zu-ZA" => "Segoe UI",
_ => null,
};
if (familyName is null)
continue;
var family = IFontFamilyId
.ListSystemFonts(false)
.FirstOrDefault(
x => x.EnglishName.Equals(familyName, StringComparison.InvariantCultureIgnoreCase));
if (family?.Fonts[family.FindBestMatch(weight, stretch, style)] is not { } font)
return;
font.AddToBuildToolkit(this, fontConfig with { MergeFont = targetFont });
return;
}
}
/// <inheritdoc/>
public void AttachExtraGlyphsForDalamudLanguage(in SafeFontConfig fontConfig)
{
var targetFont = fontConfig.MergeFont;
if (targetFont.IsNull())
targetFont = this.Font;
if (targetFont.IsNull())
return;
var dalamudConfiguration = Service<DalamudConfiguration>.Get();
if (dalamudConfiguration.EffectiveLanguage == "ko"
|| Service<DalamudIme>.GetNullable()?.EncounteredHangul is true)
@ -447,41 +571,24 @@ internal sealed partial class FontAtlasFactory
DalamudAsset.NotoSansKrRegular,
fontConfig with
{
GlyphRanges = ImGuiHelpers.CreateImGuiRangesFrom(
UnicodeRanges.HangulJamo,
UnicodeRanges.HangulCompatibilityJamo,
UnicodeRanges.HangulSyllables,
UnicodeRanges.HangulJamoExtendedA,
UnicodeRanges.HangulJamoExtendedB),
MergeFont = targetFont,
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("ko-kr").BuildExact(),
});
}
var windowsDir = Environment.GetFolderPath(Environment.SpecialFolder.Windows);
var fontPathChs = Path.Combine(windowsDir, "Fonts", "msyh.ttc");
if (!File.Exists(fontPathChs))
fontPathChs = null;
var fontPathCht = Path.Combine(windowsDir, "Fonts", "msjh.ttc");
if (!File.Exists(fontPathCht))
fontPathCht = null;
if (fontPathCht != null && Service<DalamudConfiguration>.Get().EffectiveLanguage == "tw")
if (Service<DalamudConfiguration>.Get().EffectiveLanguage == "tw")
{
this.AddFontFromFile(fontPathCht, fontConfig with
this.AttachWindowsDefaultFont(CultureInfo.GetCultureInfo("zh-hant"), fontConfig with
{
GlyphRanges = ImGuiHelpers.CreateImGuiRangesFrom(
UnicodeRanges.CjkUnifiedIdeographs,
UnicodeRanges.CjkUnifiedIdeographsExtensionA),
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("zh-hant").BuildExact(),
});
}
else if (fontPathChs != null && (Service<DalamudConfiguration>.Get().EffectiveLanguage == "zh"
|| Service<DalamudIme>.GetNullable()?.EncounteredHan is true))
else if (Service<DalamudConfiguration>.Get().EffectiveLanguage == "zh"
|| Service<DalamudIme>.GetNullable()?.EncounteredHan is true)
{
this.AddFontFromFile(fontPathChs, fontConfig with
this.AttachWindowsDefaultFont(CultureInfo.GetCultureInfo("zh-hans"), fontConfig with
{
GlyphRanges = ImGuiHelpers.CreateImGuiRangesFrom(
UnicodeRanges.CjkUnifiedIdeographs,
UnicodeRanges.CjkUnifiedIdeographsExtensionA),
GlyphRanges = default(FluentGlyphRangeBuilder).WithLanguage("zh-hans").BuildExact(),
});
}
}
@ -728,5 +835,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

@ -36,6 +36,9 @@ internal sealed partial class FontAtlasFactory
/// </summary>
public const string EllipsisCodepoints = "\u2026\u0085";
/// <summary>Marker for tasks on whether it's being called inside a font build cycle.</summary>
public static readonly AsyncLocal<bool> IsBuildInProgressForTask = new();
/// <summary>
/// If set, disables concurrent font build operation.
/// </summary>
@ -205,12 +208,12 @@ internal sealed partial class FontAtlasFactory
{
while (this.IsBuildInProgress)
await Task.Delay(100);
this.Garbage.Dispose();
this.Clear();
});
}
else
{
this.Garbage.Dispose();
this.Clear();
}
return newRefCount;
@ -228,6 +231,20 @@ internal sealed partial class FontAtlasFactory
var axisSubstance = this.Substances.OfType<GamePrebakedFontHandle.HandleSubstance>().Single();
return new(factory, this, axisSubstance, isAsync) { BuildStep = FontAtlasBuildStep.PreBuild };
}
public void Clear()
{
try
{
this.Garbage.Dispose();
}
catch (Exception e)
{
Log.Error(
e,
$"Disposing {nameof(FontAtlasBuiltData)} of {this.Owner?.Name ?? "???"}.");
}
}
}
private class DalamudFontAtlas : IFontAtlas, DisposeSafety.IDisposeCallback
@ -420,11 +437,28 @@ internal sealed partial class FontAtlasFactory
}
/// <inheritdoc/>
public IFontHandle NewGameFontHandle(GameFontStyle style) => this.gameFontHandleManager.NewFontHandle(style);
public IFontHandle NewGameFontHandle(GameFontStyle style)
{
if (IsBuildInProgressForTask.Value)
{
throw new InvalidOperationException(
$"{nameof(this.NewGameFontHandle)} may not be called during {nameof(this.BuildStepChange)} or the callback of {nameof(this.NewDelegateFontHandle)}.");
}
return this.gameFontHandleManager.NewFontHandle(style);
}
/// <inheritdoc/>
public IFontHandle NewDelegateFontHandle(FontAtlasBuildStepDelegate buildStepDelegate) =>
this.delegateFontHandleManager.NewFontHandle(buildStepDelegate);
public IFontHandle NewDelegateFontHandle(FontAtlasBuildStepDelegate buildStepDelegate)
{
if (IsBuildInProgressForTask.Value)
{
throw new InvalidOperationException(
$"{nameof(this.NewDelegateFontHandle)} may not be called during {nameof(this.BuildStepChange)} or the callback of {nameof(this.NewDelegateFontHandle)}.");
}
return this.delegateFontHandleManager.NewFontHandle(buildStepDelegate);
}
/// <inheritdoc/>
public void BuildFontsOnNextFrame()
@ -554,13 +588,13 @@ internal sealed partial class FontAtlasFactory
{
if (this.buildIndex != rebuildIndex)
{
data.ExplicitDisposeIgnoreExceptions();
data.Release();
return;
}
var prevBuiltData = this.builtData;
this.builtData = data;
prevBuiltData.ExplicitDisposeIgnoreExceptions();
prevBuiltData?.Release();
this.buildTask = EmptyTask;
fontsAndLocks.EnsureCapacity(data.Substances.Sum(x => x.RelevantHandles.Count));
@ -623,6 +657,8 @@ internal sealed partial class FontAtlasFactory
FontAtlasBuiltData? res = null;
nint atlasPtr = 0;
BuildToolkit? toolkit = null;
IsBuildInProgressForTask.Value = true;
try
{
res = new(this, scale);
@ -747,6 +783,7 @@ internal sealed partial class FontAtlasFactory
// ReSharper disable once ConstantConditionalAccessQualifier
toolkit?.Dispose();
this.buildQueued = false;
IsBuildInProgressForTask.Value = false;
}
unsafe bool ValidateMergeFontReferences(ImFontPtr replacementDstFont)

View file

@ -31,7 +31,7 @@ namespace Dalamud.Interface.ManagedFontAtlas.Internals;
/// </summary>
[ServiceManager.EarlyLoadedService]
internal sealed partial class FontAtlasFactory
: IServiceType, GamePrebakedFontHandle.IGameFontTextureProvider, IDisposable
: IInternalDisposableService, GamePrebakedFontHandle.IGameFontTextureProvider
{
private readonly DisposeSafety.ScopedFinalizer scopedFinalizer = new();
private readonly CancellationTokenSource cancellationTokenSource = new();
@ -166,7 +166,7 @@ internal sealed partial class FontAtlasFactory
this.dalamudAssetManager.IsStreamImmediatelyAvailable(DalamudAsset.LodestoneGameSymbol);
/// <inheritdoc/>
public void Dispose()
void IInternalDisposableService.DisposeService()
{
this.cancellationTokenSource.Cancel();
this.scopedFinalizer.Dispose();

View file

@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using System.Threading.Tasks;
using Dalamud.Interface.Internal;
@ -24,7 +25,6 @@ internal abstract class FontHandle : IFontHandle
private static readonly ConditionalWeakTable<LocalPlugin, object> NonMainThreadFontAccessWarning = new();
private static long nextNonMainThreadFontAccessWarningCheck;
private readonly InterfaceManager interfaceManager;
private readonly List<IDisposable> pushedFonts = new(8);
private IFontHandleManager? manager;
@ -36,7 +36,6 @@ internal abstract class FontHandle : IFontHandle
/// <param name="manager">An instance of <see cref="IFontHandleManager"/>.</param>
protected FontHandle(IFontHandleManager manager)
{
this.interfaceManager = Service<InterfaceManager>.Get();
this.manager = manager;
}
@ -58,7 +57,11 @@ internal abstract class FontHandle : IFontHandle
/// Gets the associated <see cref="IFontHandleManager"/>.
/// </summary>
/// <exception cref="ObjectDisposedException">When the object has already been disposed.</exception>
protected IFontHandleManager Manager => this.manager ?? throw new ObjectDisposedException(this.GetType().Name);
protected IFontHandleManager Manager =>
this.manager
?? throw new ObjectDisposedException(
this.GetType().Name,
"Did you write `using (fontHandle)` instead of `using (fontHandle.Push())`?");
/// <inheritdoc/>
public void Dispose()
@ -122,7 +125,7 @@ internal abstract class FontHandle : IFontHandle
}
}
this.interfaceManager.EnqueueDeferredDispose(locked);
Service<InterfaceManager>.Get().EnqueueDeferredDispose(locked);
return locked.ImFont;
}
@ -136,13 +139,18 @@ internal abstract class FontHandle : IFontHandle
/// An instance of <see cref="ILockedImFont"/> that <b>must</b> be disposed after use on success;
/// <c>null</c> with <paramref name="errorMessage"/> populated on failure.
/// </returns>
/// <exception cref="ObjectDisposedException">Still may be thrown.</exception>
public ILockedImFont? TryLock(out string? errorMessage)
{
IFontHandleSubstance? prevSubstance = default;
while (true)
{
var substance = this.Manager.Substance;
if (this.manager is not { } nonDisposedManager)
{
errorMessage = "The font handle has been disposed.";
return null;
}
var substance = nonDisposedManager.Substance;
// Does the associated IFontAtlas have a built substance?
if (substance is null)
@ -196,7 +204,7 @@ internal abstract class FontHandle : IFontHandle
ThreadSafety.AssertMainThread();
// Warn if the client is not properly managing the pushed font stack.
var cumulativePresentCalls = this.interfaceManager.CumulativePresentCalls;
var cumulativePresentCalls = Service<InterfaceManager>.Get().CumulativePresentCalls;
if (this.lastCumulativePresentCalls != cumulativePresentCalls)
{
this.lastCumulativePresentCalls = cumulativePresentCalls;
@ -213,7 +221,7 @@ internal abstract class FontHandle : IFontHandle
if (this.TryLock(out _) is { } locked)
{
font = locked.ImFont;
this.interfaceManager.EnqueueDeferredDispose(locked);
Service<InterfaceManager>.Get().EnqueueDeferredDispose(locked);
}
var rented = SimplePushedFont.Rent(this.pushedFonts, font);
@ -284,11 +292,15 @@ internal abstract class FontHandle : IFontHandle
{
if (disposing)
{
if (Interlocked.Exchange(ref this.manager, null) is not { } managerToDisassociate)
return;
if (this.pushedFonts.Count > 0)
Log.Warning($"{nameof(IFontHandle)}.{nameof(IDisposable.Dispose)}: fonts were still in a stack.");
this.Manager.FreeFontHandle(this);
this.manager = null;
managerToDisassociate.FreeFontHandle(this);
this.Disposed?.InvokeSafely();
this.Disposed = null;
this.ImFontChanged = null;
}
}

View file

@ -231,14 +231,6 @@ internal class GamePrebakedFontHandle : FontHandle
/// <inheritdoc/>
public IFontHandleManager Manager => this.handleManager;
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public IFontAtlasBuildToolkitPreBuild? PreBuildToolkitForApi9Compat { get; set; }
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public bool CreateFontOnAccess { get; set; }
/// <inheritdoc/>
public void Dispose()
{
@ -295,27 +287,11 @@ internal class GamePrebakedFontHandle : FontHandle
}
}
// Use this on API 10.
// /// <inheritdoc/>
// public ImFontPtr GetFontPtr(IFontHandle handle) =>
// handle is GamePrebakedFontHandle ggfh
// ? this.fonts.GetValueOrDefault(ggfh.FontStyle)?.FullRangeFont ?? default
// : default;
/// <inheritdoc/>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
public ImFontPtr GetFontPtr(IFontHandle handle)
{
if (handle is not GamePrebakedFontHandle ggfh)
return default;
if (this.fonts.GetValueOrDefault(ggfh.FontStyle)?.FullRangeFont is { } font)
return font;
if (!this.CreateFontOnAccess)
return default;
if (this.PreBuildToolkitForApi9Compat is not { } tk)
return default;
return this.GetOrCreateFont(ggfh.FontStyle, tk);
}
public ImFontPtr GetFontPtr(IFontHandle handle) =>
handle is GamePrebakedFontHandle ggfh
? this.fonts.GetValueOrDefault(ggfh.FontStyle)?.FullRangeFont ?? default
: default;
/// <inheritdoc/>
public Exception? GetBuildException(IFontHandle handle) =>

View file

@ -21,19 +21,6 @@ internal interface IFontHandleSubstance : IDisposable
/// </summary>
IFontHandleManager Manager { get; }
/// <summary>
/// Gets or sets the relevant <see cref="IFontAtlasBuildToolkitPreBuild"/> for this.
/// </summary>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
IFontAtlasBuildToolkitPreBuild? PreBuildToolkitForApi9Compat { get; set; }
/// <summary>
/// Gets or sets a value indicating whether to create a new instance of <see cref="ImGuiNET.ImFontPtr"/> on first
/// access, for compatibility with API 9.
/// </summary>
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
bool CreateFontOnAccess { get; set; }
/// <summary>
/// Gets the relevant handles.
/// </summary>