diff --git a/Dalamud/Configuration/Internal/DalamudConfiguration.cs b/Dalamud/Configuration/Internal/DalamudConfiguration.cs index 5359861cf..7930f5c79 100644 --- a/Dalamud/Configuration/Internal/DalamudConfiguration.cs +++ b/Dalamud/Configuration/Internal/DalamudConfiguration.cs @@ -130,9 +130,9 @@ namespace Dalamud.Configuration.Internal public float GlobalUiScale { get; set; } = 1.0f; /// - /// Gets or sets the game font to use for Dalamud UI. + /// Gets or sets a value indicating whether to use AXIS fonts from the game. /// - public GameFont DefaultFontFromGame { get; set; } = GameFont.Undefined; + public bool UseAxisFontsFromGame { get; set; } = false; /// /// Gets or sets a value indicating whether or not plugin UI should be hidden. diff --git a/Dalamud/Interface/GameFonts/GameFontFamily.cs b/Dalamud/Interface/GameFonts/GameFontFamily.cs new file mode 100644 index 000000000..2aa836927 --- /dev/null +++ b/Dalamud/Interface/GameFonts/GameFontFamily.cs @@ -0,0 +1,49 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dalamud.Interface.GameFonts +{ + /// + /// Enum of available game font families. + /// + public enum GameFontFamily + { + /// + /// Placeholder meaning unused. + /// + Undefined, + + /// + /// Sans-serif fonts used for the whole UI. Contains Japanese characters in addition to Latin characters. + /// + Axis, + + /// + /// Serif fonts used for job names. Contains Latin characters. + /// + Jupiter, + + /// + /// Digit-only serif fonts used for flying texts. Contains numbers. + /// + JupiterNumeric, + + /// + /// Digit-only sans-serif horizontally wide fonts used for HP/MP/IL numbers. + /// + Meidinger, + + /// + /// Sans-serif horizontally wide font used for names of gauges. Contains Latin characters. + /// + MiedingerMid, + + /// + /// Sans-serif horizontally narrow font used for addon titles. Contains Latin characters. + /// + TrumpGothic, + } +} diff --git a/Dalamud/Interface/GameFonts/GameFont.cs b/Dalamud/Interface/GameFonts/GameFontFamilyAndSize.cs similarity index 97% rename from Dalamud/Interface/GameFonts/GameFont.cs rename to Dalamud/Interface/GameFonts/GameFontFamilyAndSize.cs index f095b6fcc..1cbdf210f 100644 --- a/Dalamud/Interface/GameFonts/GameFont.cs +++ b/Dalamud/Interface/GameFonts/GameFontFamilyAndSize.cs @@ -1,9 +1,9 @@ namespace Dalamud.Interface.GameFonts { /// - /// Enum of available game fonts. + /// Enum of available game fonts in specific sizes. /// - public enum GameFont : int + public enum GameFontFamilyAndSize : int { /// /// Placeholder meaning unused. diff --git a/Dalamud/Interface/GameFonts/GameFontHandle.cs b/Dalamud/Interface/GameFonts/GameFontHandle.cs index 6d9274ac0..69e754727 100644 --- a/Dalamud/Interface/GameFonts/GameFontHandle.cs +++ b/Dalamud/Interface/GameFonts/GameFontHandle.cs @@ -10,26 +10,40 @@ namespace Dalamud.Interface.GameFonts public class GameFontHandle : IDisposable { private readonly GameFontManager manager; - private readonly GameFont font; + private readonly GameFontStyle fontStyle; /// /// Initializes a new instance of the class. /// /// GameFontManager instance. /// Font to use. - internal GameFontHandle(GameFontManager manager, GameFont font) + internal GameFontHandle(GameFontManager manager, GameFontStyle font) { this.manager = manager; - this.font = font; + this.fontStyle = font; } + /// + /// Gets the font style. + /// + public GameFontStyle Style => this.fontStyle; + + /// + /// Gets a value indicating whether this font is ready for use. + /// + public bool Available => this.manager.GetFont(this.fontStyle) != null; + /// /// Gets the font. /// - /// Corresponding font or null. - public ImFontPtr? Get() => this.manager.GetFont(this.font); + public ImFontPtr ImFont => this.manager.GetFont(this.fontStyle).Value; + + /// + /// Gets the FdtReader. + /// + public FdtReader FdtReader => this.manager.GetFdtReader(this.fontStyle.FamilyAndSize); /// - public void Dispose() => this.manager.DecreaseFontRef(this.font); + public void Dispose() => this.manager.DecreaseFontRef(this.fontStyle); } } diff --git a/Dalamud/Interface/GameFonts/GameFontManager.cs b/Dalamud/Interface/GameFonts/GameFontManager.cs index 9cca00236..34d385bba 100644 --- a/Dalamud/Interface/GameFonts/GameFontManager.cs +++ b/Dalamud/Interface/GameFonts/GameFontManager.cs @@ -33,10 +33,9 @@ namespace Dalamud.Interface.GameFonts private readonly FdtReader?[] fdts; private readonly List texturePixels; - private readonly ImFontPtr?[] fonts = new ImFontPtr?[FontNames.Length]; - - private readonly int[] fontUseCounter = new int[FontNames.Length]; - private readonly List>> glyphRectIds = new(); + private readonly Dictionary fonts = new(); + private readonly Dictionary fontUseCounter = new(); + private readonly Dictionary>> glyphRectIds = new(); /// /// Initializes a new instance of the class. @@ -60,34 +59,34 @@ namespace Dalamud.Interface.GameFonts /// /// Font to describe. /// A string in a form of "FontName (NNNpt)". - public static string DescribeFont(GameFont font) + public static string DescribeFont(GameFontFamilyAndSize font) { return font switch { - GameFont.Undefined => "-", - GameFont.Axis96 => "AXIS (9.6pt)", - GameFont.Axis12 => "AXIS (12pt)", - GameFont.Axis14 => "AXIS (14pt)", - GameFont.Axis18 => "AXIS (18pt)", - GameFont.Axis36 => "AXIS (36pt)", - GameFont.Jupiter16 => "Jupiter (16pt)", - GameFont.Jupiter20 => "Jupiter (20pt)", - GameFont.Jupiter23 => "Jupiter (23pt)", - GameFont.Jupiter45 => "Jupiter Numeric (45pt)", - GameFont.Jupiter46 => "Jupiter (46pt)", - GameFont.Jupiter90 => "Jupiter Numeric (90pt)", - GameFont.Meidinger16 => "Meidinger Numeric (16pt)", - GameFont.Meidinger20 => "Meidinger Numeric (20pt)", - GameFont.Meidinger40 => "Meidinger Numeric (40pt)", - GameFont.MiedingerMid10 => "MiedingerMid (10pt)", - GameFont.MiedingerMid12 => "MiedingerMid (12pt)", - GameFont.MiedingerMid14 => "MiedingerMid (14pt)", - GameFont.MiedingerMid18 => "MiedingerMid (18pt)", - GameFont.MiedingerMid36 => "MiedingerMid (36pt)", - GameFont.TrumpGothic184 => "Trump Gothic (18.4pt)", - GameFont.TrumpGothic23 => "Trump Gothic (23pt)", - GameFont.TrumpGothic34 => "Trump Gothic (34pt)", - GameFont.TrumpGothic68 => "Trump Gothic (68pt)", + GameFontFamilyAndSize.Undefined => "-", + GameFontFamilyAndSize.Axis96 => "AXIS (9.6pt)", + GameFontFamilyAndSize.Axis12 => "AXIS (12pt)", + GameFontFamilyAndSize.Axis14 => "AXIS (14pt)", + GameFontFamilyAndSize.Axis18 => "AXIS (18pt)", + GameFontFamilyAndSize.Axis36 => "AXIS (36pt)", + GameFontFamilyAndSize.Jupiter16 => "Jupiter (16pt)", + GameFontFamilyAndSize.Jupiter20 => "Jupiter (20pt)", + GameFontFamilyAndSize.Jupiter23 => "Jupiter (23pt)", + GameFontFamilyAndSize.Jupiter45 => "Jupiter Numeric (45pt)", + GameFontFamilyAndSize.Jupiter46 => "Jupiter (46pt)", + GameFontFamilyAndSize.Jupiter90 => "Jupiter Numeric (90pt)", + GameFontFamilyAndSize.Meidinger16 => "Meidinger Numeric (16pt)", + GameFontFamilyAndSize.Meidinger20 => "Meidinger Numeric (20pt)", + GameFontFamilyAndSize.Meidinger40 => "Meidinger Numeric (40pt)", + GameFontFamilyAndSize.MiedingerMid10 => "MiedingerMid (10pt)", + GameFontFamilyAndSize.MiedingerMid12 => "MiedingerMid (12pt)", + GameFontFamilyAndSize.MiedingerMid14 => "MiedingerMid (14pt)", + GameFontFamilyAndSize.MiedingerMid18 => "MiedingerMid (18pt)", + GameFontFamilyAndSize.MiedingerMid36 => "MiedingerMid (36pt)", + GameFontFamilyAndSize.TrumpGothic184 => "Trump Gothic (18.4pt)", + GameFontFamilyAndSize.TrumpGothic23 => "Trump Gothic (23pt)", + GameFontFamilyAndSize.TrumpGothic34 => "Trump Gothic (34pt)", + GameFontFamilyAndSize.TrumpGothic68 => "Trump Gothic (68pt)", _ => throw new ArgumentOutOfRangeException(nameof(font), font, "Invalid argument"), }; } @@ -97,15 +96,15 @@ namespace Dalamud.Interface.GameFonts /// /// Font to check. /// True if it can. - public static bool IsGenericPurposeFont(GameFont font) + public static bool IsGenericPurposeFont(GameFontFamilyAndSize font) { return font switch { - GameFont.Axis96 => true, - GameFont.Axis12 => true, - GameFont.Axis14 => true, - GameFont.Axis18 => true, - GameFont.Axis36 => true, + GameFontFamilyAndSize.Axis96 => true, + GameFontFamilyAndSize.Axis12 => true, + GameFontFamilyAndSize.Axis14 => true, + GameFontFamilyAndSize.Axis18 => true, + GameFontFamilyAndSize.Axis36 => true, _ => false, }; } @@ -174,32 +173,38 @@ namespace Dalamud.Interface.GameFonts /// /// Creates a new GameFontHandle, and increases internal font reference counter, and if it's first time use, then the font will be loaded on next font building process. /// - /// Font to use. + /// Font to use. /// Handle to game font that may or may not be ready yet. - public GameFontHandle NewFontRef(GameFont gameFont) + public GameFontHandle NewFontRef(GameFontStyle style) { - var fontIndex = (int)gameFont; var needRebuild = false; lock (this.syncRoot) { - var prev = this.fontUseCounter[fontIndex] == 0; - this.fontUseCounter[fontIndex] += 1; - needRebuild = prev != (this.fontUseCounter[fontIndex] == 0); + var prevValue = this.fontUseCounter.GetValueOrDefault(style, 0); + var newValue = this.fontUseCounter[style] = prevValue + 1; + needRebuild = (prevValue == 0) != (newValue == 0); } if (needRebuild) this.interfaceManager.RebuildFonts(); - return new(this, gameFont); + return new(this, style); } /// /// Gets the font. /// - /// Font to get. + /// Font to get. /// Corresponding font or null. - public ImFontPtr? GetFont(GameFont gameFont) => this.fonts[(int)gameFont]; + public ImFontPtr? GetFont(GameFontStyle style) => this.fonts.GetValueOrDefault(style, null); + + /// + /// Gets the corresponding FdtReader. + /// + /// Font to get. + /// Corresponding FdtReader or null. + public FdtReader? GetFdtReader(GameFontFamilyAndSize family) => this.fdts[(int)family]; /// /// Fills missing glyphs in target font from source font, if both are not null. @@ -208,9 +213,9 @@ namespace Dalamud.Interface.GameFonts /// Target font. /// Whether to copy missing glyphs only. /// Whether to call target.BuildLookupTable(). - public void CopyGlyphsAcrossFonts(ImFontPtr? source, GameFont target, bool missingOnly, bool rebuildLookupTable) + public void CopyGlyphsAcrossFonts(ImFontPtr? source, GameFontStyle target, bool missingOnly, bool rebuildLookupTable) { - GameFontManager.CopyGlyphsAcrossFonts(source, this.fonts[(int)target], missingOnly, rebuildLookupTable); + GameFontManager.CopyGlyphsAcrossFonts(source, this.fonts[target], missingOnly, rebuildLookupTable); } /// @@ -220,9 +225,9 @@ namespace Dalamud.Interface.GameFonts /// Target font. /// Whether to copy missing glyphs only. /// Whether to call target.BuildLookupTable(). - public void CopyGlyphsAcrossFonts(GameFont source, ImFontPtr? target, bool missingOnly, bool rebuildLookupTable) + public void CopyGlyphsAcrossFonts(GameFontStyle source, ImFontPtr? target, bool missingOnly, bool rebuildLookupTable) { - GameFontManager.CopyGlyphsAcrossFonts(this.fonts[(int)source], target, missingOnly, rebuildLookupTable); + GameFontManager.CopyGlyphsAcrossFonts(this.fonts[source], target, missingOnly, rebuildLookupTable); } /// @@ -232,9 +237,9 @@ namespace Dalamud.Interface.GameFonts /// Target font. /// Whether to copy missing glyphs only. /// Whether to call target.BuildLookupTable(). - public void CopyGlyphsAcrossFonts(GameFont source, GameFont target, bool missingOnly, bool rebuildLookupTable) + public void CopyGlyphsAcrossFonts(GameFontStyle source, GameFontStyle target, bool missingOnly, bool rebuildLookupTable) { - GameFontManager.CopyGlyphsAcrossFonts(this.fonts[(int)source], this.fonts[(int)target], missingOnly, rebuildLookupTable); + GameFontManager.CopyGlyphsAcrossFonts(this.fonts[source], this.fonts[target], missingOnly, rebuildLookupTable); } /// @@ -242,30 +247,38 @@ namespace Dalamud.Interface.GameFonts /// public void BuildFonts() { - this.glyphRectIds.Clear(); var io = ImGui.GetIO(); io.Fonts.TexDesiredWidth = 4096; - for (var i = 0; i < FontNames.Length; i++) - { - this.fonts[i] = null; - this.glyphRectIds.Add(new()); + this.glyphRectIds.Clear(); + this.fonts.Clear(); - var fdt = this.fdts[i]; - if (this.fontUseCounter[i] == 0 || fdt == null) + foreach (var style in this.fontUseCounter.Keys) + { + var rectIds = this.glyphRectIds[style] = new(); + + var fdt = this.fdts[(int)style.FamilyAndSize]; + if (fdt == null) continue; - Log.Information($"GameFontManager BuildFont: {FontNames[i]}"); - var font = io.Fonts.AddFontDefault(); - this.fonts[i] = font; + this.fonts[style] = font; foreach (var glyph in fdt.Glyphs) { var c = glyph.Char; if (c < 32 || c >= 0xFFFF) continue; - this.glyphRectIds[i][c] = Tuple.Create(io.Fonts.AddCustomRectFontGlyph(font, c, glyph.BoundingWidth + 1, glyph.BoundingHeight + 1, glyph.BoundingWidth + glyph.NextOffsetX, new Vector2(0, glyph.CurrentOffsetY)), glyph); + var widthAdjustment = style.CalculateWidthAdjustment(fdt, glyph); + rectIds[c] = Tuple.Create( + io.Fonts.AddCustomRectFontGlyph( + font, + c, + glyph.BoundingWidth + widthAdjustment + 1, + glyph.BoundingHeight + 1, + glyph.AdvanceWidth, + new Vector2(0, glyph.CurrentOffsetY)), + glyph); } } } @@ -279,13 +292,9 @@ namespace Dalamud.Interface.GameFonts io.Fonts.GetTexDataAsRGBA32(out byte* pixels8, out var width, out var height); var pixels32 = (uint*)pixels8; - for (var i = 0; i < this.fonts.Length; i++) + foreach (var (style, font) in this.fonts) { - if (!this.fonts[i].HasValue) - continue; - - var font = this.fonts[i]!.Value; - var fdt = this.fdts[i]; + var fdt = this.fdts[(int)style.FamilyAndSize]; var fontPtr = font.NativePtr; fontPtr->ConfigData->SizePixels = fontPtr->FontSize = fdt.FontHeader.LineHeight; fontPtr->Ascent = fdt.FontHeader.Ascent; @@ -301,75 +310,83 @@ namespace Dalamud.Interface.GameFonts } } - fixed (char* c = FontNames[i]) + fixed (char* c = FontNames[(int)style.FamilyAndSize]) { for (var j = 0; j < 40; j++) fontPtr->ConfigData->Name[j] = 0; - Encoding.UTF8.GetBytes(c, FontNames[i].Length, fontPtr->ConfigData->Name, 40); + Encoding.UTF8.GetBytes(c, FontNames[(int)style.FamilyAndSize].Length, fontPtr->ConfigData->Name, 40); } - foreach (var (c, (rectId, glyph)) in this.glyphRectIds[i]) + foreach (var (c, (rectId, glyph)) in this.glyphRectIds[style]) { var rc = io.Fonts.GetCustomRectByIndex(rectId); var sourceBuffer = this.texturePixels[glyph.TextureFileIndex]; var sourceBufferDelta = glyph.TextureChannelByteIndex; - for (var y = 0; y < glyph.BoundingHeight; y++) + var widthAdjustment = style.CalculateWidthAdjustment(fdt, glyph); + if (widthAdjustment == 0) { - for (var x = 0; x < glyph.BoundingWidth; x++) + for (var y = 0; y < glyph.BoundingHeight; y++) { - var a = sourceBuffer[sourceBufferDelta + (4 * (((glyph.TextureOffsetY + y) * fdt.FontHeader.TextureWidth) + glyph.TextureOffsetX + x))]; - pixels32[((rc.Y + y) * width) + rc.X + x] = (uint)(a << 24) | 0xFFFFFFu; + for (var x = 0; x < glyph.BoundingWidth; x++) + { + var a = sourceBuffer[sourceBufferDelta + (4 * (((glyph.TextureOffsetY + y) * fdt.FontHeader.TextureWidth) + glyph.TextureOffsetX + x))]; + pixels32[((rc.Y + y) * width) + rc.X + x] = (uint)(a << 24) | 0xFFFFFFu; + } + } + } + else + { + for (var y = 0; y < glyph.BoundingHeight; y++) + { + for (var x = 0; x < glyph.BoundingWidth + widthAdjustment; x++) + pixels32[((rc.Y + y) * width) + rc.X + x] = 0xFFFFFFu; + } + + for (int xbold = 0, xbold_ = Math.Max(1, (int)Math.Ceiling(style.Weight + 1)); xbold < xbold_; xbold++) + { + var boldStrength = Math.Min(1f, style.Weight + 1 - xbold); + for (var y = 0; y < glyph.BoundingHeight; y++) + { + float xDelta = xbold; + if (style.SkewStrength > 0) + xDelta += style.SkewStrength * (fdt.FontHeader.LineHeight - glyph.CurrentOffsetY - y) / fdt.FontHeader.LineHeight; + else if (style.SkewStrength < 0) + xDelta -= style.SkewStrength * (glyph.CurrentOffsetY + y) / fdt.FontHeader.LineHeight; + var xDeltaInt = (int)Math.Floor(xDelta); + var xness = xDelta - xDeltaInt; + for (var x = 0; x < glyph.BoundingWidth; x++) + { + var sourcePixelIndex = ((glyph.TextureOffsetY + y) * fdt.FontHeader.TextureWidth) + glyph.TextureOffsetX + x; + var a1 = sourceBuffer[sourceBufferDelta + (4 * sourcePixelIndex)]; + var a2 = x == glyph.BoundingWidth - 1 ? 0 : sourceBuffer[sourceBufferDelta + (4 * (sourcePixelIndex + 1))]; + var n = (a1 * xness) + (a2 * (1 - xness)); + var targetOffset = ((rc.Y + y) * width) + rc.X + x + xDeltaInt; + pixels8[(targetOffset * 4) + 3] = Math.Max(pixels8[(targetOffset * 4) + 3], (byte)(boldStrength * n)); + } + } } } } } - this.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, GameFont.Axis96, true, false); - this.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, GameFont.Axis12, true, false); - this.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, GameFont.Axis14, true, false); - this.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, GameFont.Axis18, true, false); - this.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, GameFont.Axis36, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis18, GameFont.Jupiter16, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Jupiter20, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Jupiter23, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Jupiter45, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Jupiter46, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Jupiter90, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis18, GameFont.Meidinger16, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Meidinger20, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.Meidinger40, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis96, GameFont.MiedingerMid10, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis12, GameFont.MiedingerMid12, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis14, GameFont.MiedingerMid14, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis18, GameFont.MiedingerMid18, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.MiedingerMid36, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis18, GameFont.TrumpGothic184, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.TrumpGothic23, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.TrumpGothic34, true, false); - this.CopyGlyphsAcrossFonts(GameFont.Axis36, GameFont.TrumpGothic68, true, false); - - foreach (var font in this.fonts) - font?.BuildLookupTable(); + foreach (var font in this.fonts.Values) + { + CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, font, true, false); + font.BuildLookupTable(); + } } /// - /// Decrease font reference counter and release if nobody is using it. + /// Decrease font reference counter. /// - /// Font to release. - internal void DecreaseFontRef(GameFont gameFont) + /// Font to release. + internal void DecreaseFontRef(GameFontStyle style) { - var fontIndex = (int)gameFont; - var needRebuild = false; - lock (this.syncRoot) { - var prev = this.fontUseCounter[fontIndex] == 0; - this.fontUseCounter[fontIndex] -= 1; - needRebuild = prev != (this.fontUseCounter[fontIndex] == 0); + if ((this.fontUseCounter[style] -= 1) == 0) + this.fontUseCounter.Remove(style); } - - if (needRebuild) - this.interfaceManager.RebuildFonts(); } private struct ImFontGlyphReal diff --git a/Dalamud/Interface/GameFonts/GameFontStyle.cs b/Dalamud/Interface/GameFonts/GameFontStyle.cs new file mode 100644 index 000000000..8a713f1cf --- /dev/null +++ b/Dalamud/Interface/GameFonts/GameFontStyle.cs @@ -0,0 +1,235 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Dalamud.Interface.GameFonts +{ + /// + /// Describes a font based on game resource file. + /// + public struct GameFontStyle + { + /// + /// Font family of the font. + /// + public GameFontFamilyAndSize FamilyAndSize; + + /// + /// Weight of the font. + /// + /// 0 is unaltered. + /// Any value greater than 0 will make it bolder. + /// + public float Weight; + + /// + /// Skewedness of the font. + /// + /// 0 is unaltered. + /// Greater than 1 will make upper part go rightwards. + /// Less than 1 will make lower part go rightwards. + /// + public float SkewStrength; + + /// + /// Initializes a new instance of the struct. + /// + /// Font family. + /// Size in points. + public GameFontStyle(GameFontFamily family, float size) + { + this.FamilyAndSize = GetRecommendedFamilyAndSize(family, size); + this.Weight = this.SkewStrength = 0f; + } + + /// + /// Initializes a new instance of the struct. + /// + /// Font family and size. + public GameFontStyle(GameFontFamilyAndSize familyAndSize) + { + this.FamilyAndSize = familyAndSize; + this.Weight = this.SkewStrength = 0f; + } + + /// + /// Gets the font family. + /// + public GameFontFamily Family => this.FamilyAndSize switch + { + GameFontFamilyAndSize.Undefined => GameFontFamily.Undefined, + GameFontFamilyAndSize.Axis96 => GameFontFamily.Axis, + GameFontFamilyAndSize.Axis12 => GameFontFamily.Axis, + GameFontFamilyAndSize.Axis14 => GameFontFamily.Axis, + GameFontFamilyAndSize.Axis18 => GameFontFamily.Axis, + GameFontFamilyAndSize.Axis36 => GameFontFamily.Axis, + GameFontFamilyAndSize.Jupiter16 => GameFontFamily.Jupiter, + GameFontFamilyAndSize.Jupiter20 => GameFontFamily.Jupiter, + GameFontFamilyAndSize.Jupiter23 => GameFontFamily.Jupiter, + GameFontFamilyAndSize.Jupiter45 => GameFontFamily.JupiterNumeric, + GameFontFamilyAndSize.Jupiter46 => GameFontFamily.Jupiter, + GameFontFamilyAndSize.Jupiter90 => GameFontFamily.JupiterNumeric, + GameFontFamilyAndSize.Meidinger16 => GameFontFamily.Meidinger, + GameFontFamilyAndSize.Meidinger20 => GameFontFamily.Meidinger, + GameFontFamilyAndSize.Meidinger40 => GameFontFamily.Meidinger, + GameFontFamilyAndSize.MiedingerMid10 => GameFontFamily.MiedingerMid, + GameFontFamilyAndSize.MiedingerMid12 => GameFontFamily.MiedingerMid, + GameFontFamilyAndSize.MiedingerMid14 => GameFontFamily.MiedingerMid, + GameFontFamilyAndSize.MiedingerMid18 => GameFontFamily.MiedingerMid, + GameFontFamilyAndSize.MiedingerMid36 => GameFontFamily.MiedingerMid, + GameFontFamilyAndSize.TrumpGothic184 => GameFontFamily.TrumpGothic, + GameFontFamilyAndSize.TrumpGothic23 => GameFontFamily.TrumpGothic, + GameFontFamilyAndSize.TrumpGothic34 => GameFontFamily.TrumpGothic, + GameFontFamilyAndSize.TrumpGothic68 => GameFontFamily.TrumpGothic, + _ => throw new InvalidOperationException(), + }; + + /// + /// Gets the font size. + /// + public float Size => this.FamilyAndSize switch + { + GameFontFamilyAndSize.Undefined => 0, + GameFontFamilyAndSize.Axis96 => 9.6f, + GameFontFamilyAndSize.Axis12 => 12, + GameFontFamilyAndSize.Axis14 => 14, + GameFontFamilyAndSize.Axis18 => 18, + GameFontFamilyAndSize.Axis36 => 36, + GameFontFamilyAndSize.Jupiter16 => 16, + GameFontFamilyAndSize.Jupiter20 => 20, + GameFontFamilyAndSize.Jupiter23 => 23, + GameFontFamilyAndSize.Jupiter45 => 45, + GameFontFamilyAndSize.Jupiter46 => 46, + GameFontFamilyAndSize.Jupiter90 => 90, + GameFontFamilyAndSize.Meidinger16 => 16, + GameFontFamilyAndSize.Meidinger20 => 20, + GameFontFamilyAndSize.Meidinger40 => 40, + GameFontFamilyAndSize.MiedingerMid10 => 10, + GameFontFamilyAndSize.MiedingerMid12 => 12, + GameFontFamilyAndSize.MiedingerMid14 => 14, + GameFontFamilyAndSize.MiedingerMid18 => 18, + GameFontFamilyAndSize.MiedingerMid36 => 36, + GameFontFamilyAndSize.TrumpGothic184 => 18.4f, + GameFontFamilyAndSize.TrumpGothic23 => 23, + GameFontFamilyAndSize.TrumpGothic34 => 34, + GameFontFamilyAndSize.TrumpGothic68 => 8, + _ => throw new InvalidOperationException(), + }; + + /// + /// Gets or sets a value indicating whether this font is bold. + /// + public bool Bold + { + get => this.Weight > 0f; + set => this.Weight = value ? 1f : 0f; + } + + /// + /// Gets or sets a value indicating whether this font is italic. + /// + public bool Italic + { + get => this.SkewStrength != 0; + set => this.SkewStrength = value ? 4 : 0; + } + + /// + /// Gets the recommend GameFontFamilyAndSize given family and size. + /// + /// Font family. + /// Font size in points. + /// Recommended GameFontFamilyAndSize. + public static GameFontFamilyAndSize GetRecommendedFamilyAndSize(GameFontFamily family, float size) + { + if (size <= 0) + return GameFontFamilyAndSize.Undefined; + + switch (family) + { + case GameFontFamily.Undefined: + return GameFontFamilyAndSize.Undefined; + + case GameFontFamily.Axis: + if (size <= 9.6) + return GameFontFamilyAndSize.Axis96; + else if (size <= 12) + return GameFontFamilyAndSize.Axis12; + else if (size <= 14) + return GameFontFamilyAndSize.Axis14; + else if (size <= 18) + return GameFontFamilyAndSize.Axis18; + else + return GameFontFamilyAndSize.Axis36; + + case GameFontFamily.Jupiter: + if (size <= 16) + return GameFontFamilyAndSize.Jupiter16; + else if (size <= 20) + return GameFontFamilyAndSize.Jupiter20; + else if (size <= 23) + return GameFontFamilyAndSize.Jupiter23; + else + return GameFontFamilyAndSize.Jupiter46; + + case GameFontFamily.JupiterNumeric: + if (size <= 45) + return GameFontFamilyAndSize.Jupiter45; + else + return GameFontFamilyAndSize.Jupiter90; + + case GameFontFamily.Meidinger: + if (size <= 16) + return GameFontFamilyAndSize.Meidinger16; + else if (size <= 20) + return GameFontFamilyAndSize.Meidinger20; + else + return GameFontFamilyAndSize.Meidinger40; + + case GameFontFamily.MiedingerMid: + if (size <= 10) + return GameFontFamilyAndSize.MiedingerMid10; + else if (size <= 12) + return GameFontFamilyAndSize.MiedingerMid12; + else if (size <= 14) + return GameFontFamilyAndSize.MiedingerMid14; + else if (size <= 18) + return GameFontFamilyAndSize.MiedingerMid18; + else + return GameFontFamilyAndSize.MiedingerMid36; + + case GameFontFamily.TrumpGothic: + if (size <= 18.4) + return GameFontFamilyAndSize.TrumpGothic184; + else if (size <= 23) + return GameFontFamilyAndSize.TrumpGothic23; + else if (size <= 34) + return GameFontFamilyAndSize.TrumpGothic34; + else + return GameFontFamilyAndSize.TrumpGothic68; + + default: + return GameFontFamilyAndSize.Undefined; + } + } + + /// + /// Calculates the adjustment to width resulting fron Weight and SkewStrength. + /// + /// Font information. + /// Glyph. + /// Width adjustment in pixel unit. + public int CalculateWidthAdjustment(FdtReader reader, FdtReader.FontTableEntry glyph) + { + var widthDelta = this.Weight; + if (this.SkewStrength > 0) + widthDelta += 1f * this.SkewStrength * (reader.FontHeader.LineHeight - glyph.CurrentOffsetY) / reader.FontHeader.LineHeight; + else if (this.SkewStrength < 0) + widthDelta -= 1f * this.SkewStrength * (glyph.CurrentOffsetY + glyph.BoundingHeight) / reader.FontHeader.LineHeight; + + return (int)Math.Ceiling(widthDelta); + } + } +} diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index 1e9654dc0..58f18bf70 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -57,8 +57,7 @@ namespace Dalamud.Interface.Internal private readonly SwapChainVtableResolver address; private RawDX11Scene? scene; - private GameFont overwriteDefaultFontFromGameFont = GameFont.Undefined; - private GameFontHandle? overwriteDefaultFontFromGameFontHandle; + private GameFontHandle? axisFontHandle; // can't access imgui IO before first present call private bool lastWantCapture = false; @@ -313,16 +312,7 @@ namespace Dalamud.Interface.Internal if (!this.isRebuildingFonts) { Log.Verbose("[FONT] RebuildFonts() trigger"); - var configuration = Service.Get(); - if (this.overwriteDefaultFontFromGameFont != configuration.DefaultFontFromGame) - { - this.overwriteDefaultFontFromGameFont = configuration.DefaultFontFromGame; - this.overwriteDefaultFontFromGameFontHandle?.Dispose(); - if (configuration.DefaultFontFromGame == GameFont.Undefined) - this.overwriteDefaultFontFromGameFontHandle = null; - else - this.overwriteDefaultFontFromGameFontHandle = Service.Get().NewFontRef(configuration.DefaultFontFromGame); - } + this.SetAxisFonts(); this.isRebuildingFonts = true; this.scene.OnNewRenderFrame += this.RebuildFontsInternal; @@ -342,6 +332,26 @@ namespace Dalamud.Interface.Internal Util.Fatal($"One or more files required by XIVLauncher were not found.\nPlease restart and report this error if it occurs again.\n\n{path}", "Error"); } + private void SetAxisFonts() + { + var configuration = Service.Get(); + if (configuration.UseAxisFontsFromGame) + { + var currentFamilyAndSize = GameFontStyle.GetRecommendedFamilyAndSize(GameFontFamily.Axis, this.axisFontHandle?.Style.Size ?? 0f); + var expectedFamilyAndSize = GameFontStyle.GetRecommendedFamilyAndSize(GameFontFamily.Axis, 12 * ImGui.GetIO().FontGlobalScale); + if (currentFamilyAndSize == expectedFamilyAndSize) + return; + + this.axisFontHandle?.Dispose(); + this.axisFontHandle = Service.Get().NewFontRef(new(expectedFamilyAndSize)); + } + else + { + this.axisFontHandle?.Dispose(); + this.axisFontHandle = null; + } + } + /* * NOTE(goat): When hooking ReShade DXGISwapChain::runtime_present, this is missing the syncInterval arg. * Seems to work fine regardless, I guess, so whatever. @@ -403,15 +413,7 @@ namespace Dalamud.Interface.Internal this.scene.OnBuildUI += this.Display; this.scene.OnNewInputFrame += this.OnNewInputFrame; - if (this.overwriteDefaultFontFromGameFont != configuration.DefaultFontFromGame) - { - this.overwriteDefaultFontFromGameFont = configuration.DefaultFontFromGame; - this.overwriteDefaultFontFromGameFontHandle?.Dispose(); - if (configuration.DefaultFontFromGame == GameFont.Undefined) - this.overwriteDefaultFontFromGameFontHandle = null; - else - this.overwriteDefaultFontFromGameFontHandle = Service.Get().NewFontRef(configuration.DefaultFontFromGame); - } + this.SetAxisFonts(); this.SetupFonts(); @@ -591,7 +593,7 @@ namespace Dalamud.Interface.Internal ImGui.GetIO().Fonts.Build(); gameFontManager.AfterBuildFonts(); - GameFontManager.CopyGlyphsAcrossFonts(this.overwriteDefaultFontFromGameFontHandle?.Get(), DefaultFont, false, true); + GameFontManager.CopyGlyphsAcrossFonts(this.axisFontHandle?.ImFont, DefaultFont, false, true); Log.Verbose("[FONT] Invoke OnAfterBuildFonts"); this.AfterBuildFonts?.Invoke(); diff --git a/Dalamud/Interface/Internal/Windows/SettingsWindow.cs b/Dalamud/Interface/Internal/Windows/SettingsWindow.cs index 6fa6df808..ac01392a7 100644 --- a/Dalamud/Interface/Internal/Windows/SettingsWindow.cs +++ b/Dalamud/Interface/Internal/Windows/SettingsWindow.cs @@ -28,8 +28,6 @@ namespace Dalamud.Interface.Internal.Windows private const float MinScale = 0.3f; private const float MaxScale = 2.0f; - private readonly List validFontChoices; - private readonly string[] validFontNames; private readonly string[] languages; private readonly string[] locLanguages; private int langIndex; @@ -40,6 +38,7 @@ namespace Dalamud.Interface.Internal.Windows private bool doCfChatMessage; private float globalUiScale; + private bool doUseAxisFontsFromGame; private bool doToggleUiHide; private bool doToggleUiHideDuringCutscenes; private bool doToggleUiHideDuringGpose; @@ -69,8 +68,6 @@ namespace Dalamud.Interface.Internal.Windows private bool doButtonsSystemMenu; private bool disableRmtFiltering; - private int validFontIndex; - #region Experimental private bool doPluginTest; @@ -94,6 +91,7 @@ namespace Dalamud.Interface.Internal.Windows this.doCfChatMessage = configuration.DutyFinderChatMessage; this.globalUiScale = configuration.GlobalUiScale; + this.doUseAxisFontsFromGame = configuration.UseAxisFontsFromGame; this.doToggleUiHide = configuration.ToggleUiHide; this.doToggleUiHideDuringCutscenes = configuration.ToggleUiHideDuringCutscenes; this.doToggleUiHideDuringGpose = configuration.ToggleUiHideDuringGpose; @@ -116,10 +114,6 @@ namespace Dalamud.Interface.Internal.Windows this.doButtonsSystemMenu = configuration.DoButtonsSystemMenu; this.disableRmtFiltering = configuration.DisableRmtFiltering; - this.validFontChoices = Enum.GetValues().Where(x => x == GameFont.Undefined || GameFontManager.IsGenericPurposeFont(x)).ToList(); - this.validFontNames = this.validFontChoices.Select(x => GameFontManager.DescribeFont(x)).ToArray(); - this.validFontIndex = Math.Max(0, this.validFontChoices.IndexOf(configuration.DefaultFontFromGame)); - this.languages = Localization.ApplicableLangCodes.Prepend("en").ToArray(); try { @@ -286,20 +280,19 @@ namespace Dalamud.Interface.Internal.Windows { this.globalUiScale = 1.0f; ImGui.GetIO().FontGlobalScale = this.globalUiScale; + Service.Get().RebuildFonts(); } if (ImGui.DragFloat("##DalamudSettingsGlobalUiScaleDrag", ref this.globalUiScale, 0.005f, MinScale, MaxScale, "%.2f")) + { ImGui.GetIO().FontGlobalScale = this.globalUiScale; + Service.Get().RebuildFonts(); + } ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingsGlobalUiScaleHint", "Scale all XIVLauncher UI elements - useful for 4K displays.")); ImGuiHelpers.ScaledDummy(10, 16); - ImGui.Text(Loc.Localize("DalamudSettingsGlobalFont", "Global Font")); - ImGui.Combo("##DalamudSettingsGlobalFontDrag", ref this.validFontIndex, this.validFontNames, this.validFontNames.Length); - - ImGuiHelpers.ScaledDummy(10, 16); - if (ImGui.Button(Loc.Localize("DalamudSettingsOpenStyleEditor", "Open Style Editor"))) { Service.Get().OpenStyleEditor(); @@ -311,6 +304,9 @@ namespace Dalamud.Interface.Internal.Windows ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingToggleUiHideOptOutNote", "Plugins may independently opt out of the settings below.")); + ImGui.Checkbox(Loc.Localize("DalamudSettingToggleAxisFonts", "Use AXIS fonts as default Dalamud font"), ref this.doUseAxisFontsFromGame); + ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingToggleUiAxisFontsHint", "Use AXIS fonts (the game's main UI fonts) as default Dalamud font.")); + ImGui.Checkbox(Loc.Localize("DalamudSettingToggleUiHide", "Hide plugin UI when the game UI is toggled off"), ref this.doToggleUiHide); ImGui.TextColored(ImGuiColors.DalamudGrey, Loc.Localize("DalamudSettingToggleUiHideHint", "Hide any open windows by plugins when toggling the game overlay.")); @@ -814,7 +810,7 @@ namespace Dalamud.Interface.Internal.Windows configuration.IsFocusManagementEnabled = this.doFocus; configuration.ShowTsm = this.doTsm; - configuration.DefaultFontFromGame = this.validFontChoices[this.validFontIndex]; + configuration.UseAxisFontsFromGame = this.doUseAxisFontsFromGame; // This is applied every frame in InterfaceManager::CheckViewportState() configuration.IsDisableViewport = !this.doViewport; @@ -858,9 +854,8 @@ namespace Dalamud.Interface.Internal.Windows configuration.Save(); - Service.Get().RebuildFonts(); - _ = Service.Get().ReloadPluginMastersAsync(); + Service.Get().RebuildFonts(); } } } diff --git a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs index c57a130b4..b4c089fbe 100644 --- a/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs +++ b/Dalamud/Interface/Internal/Windows/TitleScreenMenuWindow.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.IO; using System.Numerics; @@ -8,6 +8,7 @@ using Dalamud.Game; using Dalamud.Game.ClientState; using Dalamud.Game.Gui; using Dalamud.Interface.Animation.EasingFunctions; +using Dalamud.Interface.GameFonts; using Dalamud.Interface.Windowing; using ImGuiNET; using ImGuiScene; @@ -19,6 +20,7 @@ namespace Dalamud.Interface.Internal.Windows /// internal class TitleScreenMenuWindow : Window, IDisposable { + private const float TargetFontSize = 16.2f; private readonly TextureWrap shadeTexture; private readonly Dictionary shadeEasings = new(); @@ -27,6 +29,8 @@ namespace Dalamud.Interface.Internal.Windows private InOutCubic? fadeOutEasing; + private GameFontHandle? axisFontHandle; + private State state = State.Hide; /// @@ -67,14 +71,19 @@ namespace Dalamud.Interface.Internal.Windows /// public override void PreDraw() { + this.SetAxisFonts(); ImGui.PushStyleVar(ImGuiStyleVar.ItemSpacing, new Vector2(0, 0)); ImGui.PushStyleVar(ImGuiStyleVar.WindowPadding, new Vector2(0, 0)); + if (this.axisFontHandle?.Available ?? false) + ImGui.PushFont(this.axisFontHandle.ImFont); base.PreDraw(); } /// public override void PostDraw() { + if (this.axisFontHandle?.Available ?? false) + ImGui.PopFont(); ImGui.PopStyleVar(2); base.PostDraw(); } @@ -90,128 +99,143 @@ namespace Dalamud.Interface.Internal.Windows /// public override void Draw() { - ImGui.SetWindowFontScale(1.3f); + ImGui.SetWindowFontScale(TargetFontSize / ImGui.GetFont().FontSize * 4 / 3); var tsm = Service.Get(); switch (this.state) { case State.Show: - { - for (var i = 0; i < tsm.Entries.Count; i++) { - var entry = tsm.Entries[i]; - - if (!this.moveEasings.TryGetValue(entry.Id, out var moveEasing)) + for (var i = 0; i < tsm.Entries.Count; i++) { - moveEasing = new InOutQuint(TimeSpan.FromMilliseconds(400)); - this.moveEasings.Add(entry.Id, moveEasing); + var entry = tsm.Entries[i]; + + if (!this.moveEasings.TryGetValue(entry.Id, out var moveEasing)) + { + moveEasing = new InOutQuint(TimeSpan.FromMilliseconds(400)); + this.moveEasings.Add(entry.Id, moveEasing); + } + + if (!moveEasing.IsRunning && !moveEasing.IsDone) + { + moveEasing.Restart(); + } + + if (moveEasing.IsDone) + { + moveEasing.Stop(); + } + + moveEasing.Update(); + + var finalPos = (i + 1) * this.shadeTexture.Height; + var pos = moveEasing.Value * finalPos; + + // FIXME(goat): Sometimes, easings can overshoot and bring things out of alignment. + if (moveEasing.IsDone) + { + pos = finalPos; + } + + this.DrawEntry(entry, moveEasing.IsRunning && i != 0, true, i == 0, true); + + var cursor = ImGui.GetCursorPos(); + cursor.Y = (float)pos; + ImGui.SetCursorPos(cursor); } - if (!moveEasing.IsRunning && !moveEasing.IsDone) + if (!ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | + ImGuiHoveredFlags.AllowWhenOverlapped | + ImGuiHoveredFlags.AllowWhenBlockedByActiveItem)) { - moveEasing.Restart(); + this.state = State.FadeOut; } - if (moveEasing.IsDone) - { - moveEasing.Stop(); - } - - moveEasing.Update(); - - var finalPos = (i + 1) * this.shadeTexture.Height; - var pos = moveEasing.Value * finalPos; - - // FIXME(goat): Sometimes, easings can overshoot and bring things out of alignment. - if (moveEasing.IsDone) - { - pos = finalPos; - } - - this.DrawEntry(entry, moveEasing.IsRunning && i != 0, true, i == 0, true); - - var cursor = ImGui.GetCursorPos(); - cursor.Y = (float)pos; - ImGui.SetCursorPos(cursor); + break; } - if (!ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | - ImGuiHoveredFlags.AllowWhenOverlapped | - ImGuiHoveredFlags.AllowWhenBlockedByActiveItem)) - { - this.state = State.FadeOut; - } - - break; - } - case State.FadeOut: - { - this.fadeOutEasing ??= new InOutCubic(TimeSpan.FromMilliseconds(400)) { - IsInverse = true, - }; + this.fadeOutEasing ??= new InOutCubic(TimeSpan.FromMilliseconds(400)) + { + IsInverse = true, + }; - if (!this.fadeOutEasing.IsRunning && !this.fadeOutEasing.IsDone) - { - this.fadeOutEasing.Restart(); + if (!this.fadeOutEasing.IsRunning && !this.fadeOutEasing.IsDone) + { + this.fadeOutEasing.Restart(); + } + + if (this.fadeOutEasing.IsDone) + { + this.fadeOutEasing.Stop(); + } + + this.fadeOutEasing.Update(); + + ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value); + + for (var i = 0; i < tsm.Entries.Count; i++) + { + var entry = tsm.Entries[i]; + + var finalPos = (i + 1) * this.shadeTexture.Height; + + this.DrawEntry(entry, i != 0, true, i == 0, false); + + var cursor = ImGui.GetCursorPos(); + cursor.Y = finalPos; + ImGui.SetCursorPos(cursor); + } + + ImGui.PopStyleVar(); + + var isHover = ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | + ImGuiHoveredFlags.AllowWhenOverlapped | + ImGuiHoveredFlags.AllowWhenBlockedByActiveItem); + + if (!isHover && this.fadeOutEasing!.IsDone) + { + this.state = State.Hide; + this.fadeOutEasing = null; + } + else if (isHover) + { + this.state = State.Show; + this.fadeOutEasing = null; + } + + break; } - if (this.fadeOutEasing.IsDone) - { - this.fadeOutEasing.Stop(); - } - - this.fadeOutEasing.Update(); - - ImGui.PushStyleVar(ImGuiStyleVar.Alpha, (float)this.fadeOutEasing.Value); - - for (var i = 0; i < tsm.Entries.Count; i++) - { - var entry = tsm.Entries[i]; - - var finalPos = (i + 1) * this.shadeTexture.Height; - - this.DrawEntry(entry, i != 0, true, i == 0, false); - - var cursor = ImGui.GetCursorPos(); - cursor.Y = finalPos; - ImGui.SetCursorPos(cursor); - } - - ImGui.PopStyleVar(); - - var isHover = ImGui.IsWindowHovered(ImGuiHoveredFlags.RootAndChildWindows | - ImGuiHoveredFlags.AllowWhenOverlapped | - ImGuiHoveredFlags.AllowWhenBlockedByActiveItem); - - if (!isHover && this.fadeOutEasing!.IsDone) - { - this.state = State.Hide; - this.fadeOutEasing = null; - } - else if (isHover) - { - this.state = State.Show; - this.fadeOutEasing = null; - } - - break; - } - case State.Hide: - { - if (this.DrawEntry(tsm.Entries[0], true, false, true, true)) { - this.state = State.Show; - } + if (this.DrawEntry(tsm.Entries[0], true, false, true, true)) + { + this.state = State.Show; + } - this.moveEasings.Clear(); - this.logoEasings.Clear(); - this.shadeEasings.Clear(); - break; - } + this.moveEasings.Clear(); + this.logoEasings.Clear(); + this.shadeEasings.Clear(); + break; + } + } + } + + private void SetAxisFonts() + { + var configuration = Service.Get(); + if (configuration.UseAxisFontsFromGame) + { + if (this.axisFontHandle == null) + this.axisFontHandle = Service.Get().NewFontRef(new(GameFontFamily.Axis, TargetFontSize)); + } + else + { + this.axisFontHandle?.Dispose(); + this.axisFontHandle = null; } } diff --git a/Dalamud/Interface/UiBuilder.cs b/Dalamud/Interface/UiBuilder.cs index 35c82102b..e3f85426c 100644 --- a/Dalamud/Interface/UiBuilder.cs +++ b/Dalamud/Interface/UiBuilder.cs @@ -215,9 +215,9 @@ namespace Dalamud.Interface /// /// Gets a game font. /// - /// Font to get. + /// Font to get. /// Handle to the game font which may or may not be available for use yet. - public GameFontHandle GetGameFontHandle(GameFont gameFont) => Service.Get().NewFontRef(gameFont); + public GameFontHandle GetGameFontHandle(GameFontStyle style) => Service.Get().NewFontRef(style); /// /// Call this to queue a rebuild of the font atlas.