From 02d19df0f76cbda80695afe077b830e0fa21f75a Mon Sep 17 00:00:00 2001 From: goaaats Date: Thu, 12 May 2022 10:59:53 +0200 Subject: [PATCH] refactor: move CopyGlyphsAcrossFonts into ImGuiHelpers.cs --- .../Interface/GameFonts/GameFontManager.cs | 10 +- Dalamud/Interface/ImGuiHelpers.cs | 100 ++++++++++++++++++ .../Interface/Internal/InterfaceManager.cs | 6 +- Dalamud/Utility/Util.cs | 94 ---------------- 4 files changed, 108 insertions(+), 102 deletions(-) diff --git a/Dalamud/Interface/GameFonts/GameFontManager.cs b/Dalamud/Interface/GameFonts/GameFontManager.cs index fec324a73..933558c09 100644 --- a/Dalamud/Interface/GameFonts/GameFontManager.cs +++ b/Dalamud/Interface/GameFonts/GameFontManager.cs @@ -136,7 +136,7 @@ namespace Dalamud.Interface.GameFonts font->Descent /= fontScale; if (font->ConfigData != null) font->ConfigData->SizePixels /= fontScale; - var glyphs = (Util.ImFontGlyphReal*)font->Glyphs.Data; + var glyphs = (ImGuiHelpers.ImFontGlyphReal*)font->Glyphs.Data; for (int i = 0, i_ = font->Glyphs.Size; i < i_; i++) { var glyph = &glyphs[i]; @@ -212,7 +212,7 @@ namespace Dalamud.Interface.GameFonts /// Whether to call target.BuildLookupTable(). public void CopyGlyphsAcrossFonts(ImFontPtr? source, GameFontStyle target, bool missingOnly, bool rebuildLookupTable) { - Util.CopyGlyphsAcrossFonts(source, this.fonts[target], missingOnly, rebuildLookupTable); + ImGuiHelpers.CopyGlyphsAcrossFonts(source, this.fonts[target], missingOnly, rebuildLookupTable); } /// @@ -224,7 +224,7 @@ namespace Dalamud.Interface.GameFonts /// Whether to call target.BuildLookupTable(). public void CopyGlyphsAcrossFonts(GameFontStyle source, ImFontPtr? target, bool missingOnly, bool rebuildLookupTable) { - Util.CopyGlyphsAcrossFonts(this.fonts[source], target, missingOnly, rebuildLookupTable); + ImGuiHelpers.CopyGlyphsAcrossFonts(this.fonts[source], target, missingOnly, rebuildLookupTable); } /// @@ -236,7 +236,7 @@ namespace Dalamud.Interface.GameFonts /// Whether to call target.BuildLookupTable(). public void CopyGlyphsAcrossFonts(GameFontStyle source, GameFontStyle target, bool missingOnly, bool rebuildLookupTable) { - Util.CopyGlyphsAcrossFonts(this.fonts[source], this.fonts[target], missingOnly, rebuildLookupTable); + ImGuiHelpers.CopyGlyphsAcrossFonts(this.fonts[source], this.fonts[target], missingOnly, rebuildLookupTable); } /// @@ -364,7 +364,7 @@ namespace Dalamud.Interface.GameFonts } } - Util.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, font, true, false); + ImGuiHelpers.CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, font, true, false); UnscaleFont(font, 1 / scale, false); font.BuildLookupTable(); } diff --git a/Dalamud/Interface/ImGuiHelpers.cs b/Dalamud/Interface/ImGuiHelpers.cs index b71b7cdd5..99590af18 100644 --- a/Dalamud/Interface/ImGuiHelpers.cs +++ b/Dalamud/Interface/ImGuiHelpers.cs @@ -1,4 +1,7 @@ +using System; using System.Collections.Generic; +using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.Numerics; using ImGuiNET; @@ -136,6 +139,67 @@ namespace Dalamud.Interface /// The text to write. public static void SafeTextWrapped(string text) => ImGui.TextWrapped(text.Replace("%", "%%")); + /// + /// Fills missing glyphs in target font from source font, if both are not null. + /// + /// Source font. + /// Target font. + /// Whether to copy missing glyphs only. + /// Whether to call target.BuildLookupTable(). + /// Low codepoint range to copy. + /// High codepoing range to copy. + public static void CopyGlyphsAcrossFonts(ImFontPtr? source, ImFontPtr? target, bool missingOnly, bool rebuildLookupTable, int rangeLow = 32, int rangeHigh = 0xFFFE) + { + if (!source.HasValue || !target.HasValue) + return; + + var scale = target.Value!.FontSize / source.Value!.FontSize; + unsafe + { + var glyphs = (ImFontGlyphReal*)source.Value!.Glyphs.Data; + for (int j = 0, k = source.Value!.Glyphs.Size; j < k; j++) + { + Debug.Assert(glyphs != null, nameof(glyphs) + " != null"); + + var glyph = &glyphs[j]; + if (glyph->Codepoint < rangeLow || glyph->Codepoint > rangeHigh) + continue; + + var prevGlyphPtr = (ImFontGlyphReal*)target.Value!.FindGlyphNoFallback((ushort)glyph->Codepoint).NativePtr; + if ((IntPtr)prevGlyphPtr == IntPtr.Zero) + { + target.Value!.AddGlyph( + target.Value!.ConfigData, + (ushort)glyph->Codepoint, + glyph->X0 * scale, + ((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent, + glyph->X1 * scale, + ((glyph->Y1 - source.Value!.Ascent) * scale) + target.Value!.Ascent, + glyph->U0, + glyph->V0, + glyph->U1, + glyph->V1, + glyph->AdvanceX * scale); + } + else if (!missingOnly) + { + prevGlyphPtr->X0 = glyph->X0 * scale; + prevGlyphPtr->Y0 = ((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent; + prevGlyphPtr->X1 = glyph->X1 * scale; + prevGlyphPtr->Y1 = ((glyph->Y1 - source.Value!.Ascent) * scale) + target.Value!.Ascent; + prevGlyphPtr->U0 = glyph->U0; + prevGlyphPtr->V0 = glyph->V0; + prevGlyphPtr->U1 = glyph->U1; + prevGlyphPtr->V1 = glyph->V1; + prevGlyphPtr->AdvanceX = glyph->AdvanceX * scale; + } + } + } + + if (rebuildLookupTable) + target.Value!.BuildLookupTable(); + } + /// /// Get data needed for each new frame. /// @@ -143,5 +207,41 @@ namespace Dalamud.Interface { GlobalScale = ImGui.GetIO().FontGlobalScale; } + + /// + /// ImFontGlyph the correct version. + /// + [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1600:Elements should be documented", Justification = "ImGui internals")] + public struct ImFontGlyphReal + { + public uint ColoredVisibleCodepoint; + public float AdvanceX; + public float X0; + public float Y0; + public float X1; + public float Y1; + public float U0; + public float V0; + public float U1; + public float V1; + + public bool Colored + { + get => ((this.ColoredVisibleCodepoint >> 0) & 1) != 0; + set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFEu) | (value ? 1u : 0u); + } + + public bool Visible + { + get => ((this.ColoredVisibleCodepoint >> 1) & 1) != 0; + set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFDu) | (value ? 2u : 0u); + } + + public int Codepoint + { + get => (int)(this.ColoredVisibleCodepoint >> 2); + set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 3u) | ((uint)this.Codepoint << 2); + } + } } } diff --git a/Dalamud/Interface/Internal/InterfaceManager.cs b/Dalamud/Interface/Internal/InterfaceManager.cs index 1d31e4df9..6de07e0bd 100644 --- a/Dalamud/Interface/Internal/InterfaceManager.cs +++ b/Dalamud/Interface/Internal/InterfaceManager.cs @@ -934,14 +934,14 @@ namespace Dalamud.Interface.Internal font.Descent = mod.SourceAxis.ImFont.Descent; font.FallbackChar = mod.SourceAxis.ImFont.FallbackChar; font.EllipsisChar = mod.SourceAxis.ImFont.EllipsisChar; - Util.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, false, false); + ImGuiHelpers.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, false, false); } else if (mod.Axis == TargetFontModification.AxisMode.GameGlyphsOnly) { Log.Verbose("[FONT] {0}: Overwrite game specific glyphs from AXIS of size {1}px", mod.Name, mod.SourceAxis.ImFont.FontSize, font.FontSize); if (!this.UseAxis && font.NativePtr == DefaultFont.NativePtr) mod.SourceAxis.ImFont.FontSize -= 1; - Util.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, true, false, 0xE020, 0xE0DB); + ImGuiHelpers.CopyGlyphsAcrossFonts(mod.SourceAxis.ImFont, font, true, false, 0xE020, 0xE0DB); if (!this.UseAxis && font.NativePtr == DefaultFont.NativePtr) mod.SourceAxis.ImFont.FontSize += 1; } @@ -951,7 +951,7 @@ namespace Dalamud.Interface.Internal } // Fill missing glyphs in MonoFont from DefaultFont - Util.CopyGlyphsAcrossFonts(DefaultFont, MonoFont, true, false); + ImGuiHelpers.CopyGlyphsAcrossFonts(DefaultFont, MonoFont, true, false); for (int i = 0, i_ = ioFonts.Fonts.Size; i < i_; i++) { diff --git a/Dalamud/Utility/Util.cs b/Dalamud/Utility/Util.cs index 4eb178854..9c02efe2c 100644 --- a/Dalamud/Utility/Util.cs +++ b/Dalamud/Utility/Util.cs @@ -526,65 +526,6 @@ namespace Dalamud.Utility Process.Start(process); } - /// - /// Fills missing glyphs in target font from source font, if both are not null. - /// - /// Source font. - /// Target font. - /// Whether to copy missing glyphs only. - /// Whether to call target.BuildLookupTable(). - /// Low codepoint range to copy. - /// High codepoing range to copy. - public static void CopyGlyphsAcrossFonts(ImFontPtr? source, ImFontPtr? target, bool missingOnly, bool rebuildLookupTable, int rangeLow = 32, int rangeHigh = 0xFFFE) - { - if (!source.HasValue || !target.HasValue) - return; - - var scale = target.Value!.FontSize / source.Value!.FontSize; - unsafe - { - var glyphs = (ImFontGlyphReal*)source.Value!.Glyphs.Data; - for (int j = 0, j_ = source.Value!.Glyphs.Size; j < j_; j++) - { - var glyph = &glyphs[j]; - if (glyph->Codepoint < rangeLow || glyph->Codepoint > rangeHigh) - continue; - - var prevGlyphPtr = (ImFontGlyphReal*)target.Value!.FindGlyphNoFallback((ushort)glyph->Codepoint).NativePtr; - if ((IntPtr)prevGlyphPtr == IntPtr.Zero) - { - target.Value!.AddGlyph( - target.Value!.ConfigData, - (ushort)glyph->Codepoint, - glyph->X0 * scale, - ((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent, - glyph->X1 * scale, - ((glyph->Y1 - source.Value!.Ascent) * scale) + target.Value!.Ascent, - glyph->U0, - glyph->V0, - glyph->U1, - glyph->V1, - glyph->AdvanceX * scale); - } - else if (!missingOnly) - { - prevGlyphPtr->X0 = glyph->X0 * scale; - prevGlyphPtr->Y0 = ((glyph->Y0 - source.Value!.Ascent) * scale) + target.Value!.Ascent; - prevGlyphPtr->X1 = glyph->X1 * scale; - prevGlyphPtr->Y1 = ((glyph->Y1 - source.Value!.Ascent) * scale) + target.Value!.Ascent; - prevGlyphPtr->U0 = glyph->U0; - prevGlyphPtr->V0 = glyph->V0; - prevGlyphPtr->U1 = glyph->U1; - prevGlyphPtr->V1 = glyph->V1; - prevGlyphPtr->AdvanceX = glyph->AdvanceX * scale; - } - } - } - - if (rebuildLookupTable) - target.Value!.BuildLookupTable(); - } - /// /// Dispose this object. /// @@ -649,40 +590,5 @@ namespace Dalamud.Utility } } } - - /// - /// ImFontGlyph the correct version. - /// - public struct ImFontGlyphReal - { - public uint ColoredVisibleCodepoint; - public float AdvanceX; - public float X0; - public float Y0; - public float X1; - public float Y1; - public float U0; - public float V0; - public float U1; - public float V1; - - public bool Colored - { - get => ((this.ColoredVisibleCodepoint >> 0) & 1) != 0; - set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFEu) | (value ? 1u : 0u); - } - - public bool Visible - { - get => ((this.ColoredVisibleCodepoint >> 1) & 1) != 0; - set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 0xFFFFFFFDu) | (value ? 2u : 0u); - } - - public int Codepoint - { - get => (int)(this.ColoredVisibleCodepoint >> 2); - set => this.ColoredVisibleCodepoint = (this.ColoredVisibleCodepoint & 3u) | ((uint)this.Codepoint << 2); - } - } } }