mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Add SetFontScaleMode(ImFontPtr, FontScaleMode) (#1666)
* Add SetFontScaleMode(ImFontPtr, FontScaleMode) `IgnoreGlobalScale` was advertised as "excludes the given font from global scaling", but the intent I had in mind was "excludes the given font from being scaled in any manner". As the latter functionality is needed, obsoleted `IgnoreGlobalScale` and added `SetFontScaleMode`. * Make it correct * Name consistency
This commit is contained in:
parent
7dc99c9307
commit
2d8b71c647
9 changed files with 166 additions and 66 deletions
|
|
@ -31,6 +31,8 @@ public interface IFontSpec
|
||||||
/// <param name="atlas">The atlas to bind this font handle to.</param>
|
/// <param name="atlas">The atlas to bind this font handle to.</param>
|
||||||
/// <param name="callback">Optional callback to be called after creating the font handle.</param>
|
/// <param name="callback">Optional callback to be called after creating the font handle.</param>
|
||||||
/// <returns>The new font handle.</returns>
|
/// <returns>The new font handle.</returns>
|
||||||
|
/// <remarks><see cref="IFontAtlasBuildToolkit.Font"/> will be set when <paramref name="callback"/> is invoked.
|
||||||
|
/// </remarks>
|
||||||
IFontHandle CreateFontHandle(IFontAtlas atlas, FontAtlasBuildStepDelegate? callback = null);
|
IFontHandle CreateFontHandle(IFontAtlas atlas, FontAtlasBuildStepDelegate? callback = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,9 @@ public record SingleFontSpec : IFontSpec
|
||||||
tk.RegisterPostBuild(
|
tk.RegisterPostBuild(
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
var roundUnit = tk.IsGlobalScaleIgnored(font) ? 1 : 1 / tk.Scale;
|
// Multiplication by scale will be done with global scale, outside of this handling.
|
||||||
|
var scale = tk.GetFontScaleMode(font) == FontScaleMode.UndoGlobalScale ? 1 / tk.Scale : 1;
|
||||||
|
var roundUnit = tk.GetFontScaleMode(font) == FontScaleMode.SkipHandling ? 1 : 1 / tk.Scale;
|
||||||
var newAscent = MathF.Round((font.Ascent * this.LineHeight) / roundUnit) * roundUnit;
|
var newAscent = MathF.Round((font.Ascent * this.LineHeight) / roundUnit) * roundUnit;
|
||||||
var newFontSize = MathF.Round((font.FontSize * this.LineHeight) / roundUnit) * roundUnit;
|
var newFontSize = MathF.Round((font.FontSize * this.LineHeight) / roundUnit) * roundUnit;
|
||||||
var shiftDown = MathF.Round((newFontSize - font.FontSize) / 2f / roundUnit) * roundUnit;
|
var shiftDown = MathF.Round((newFontSize - font.FontSize) / 2f / roundUnit) * roundUnit;
|
||||||
|
|
@ -129,13 +131,10 @@ public record SingleFontSpec : IFontSpec
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// `/ roundUnit` = `* scale`
|
var dax = MathF.Round((this.LetterSpacing * scale) / roundUnit) * roundUnit;
|
||||||
var dax = MathF.Round(this.LetterSpacing / roundUnit / roundUnit) * roundUnit;
|
var dxy0 = this.GlyphOffset * scale;
|
||||||
var dxy0 = this.GlyphOffset / roundUnit;
|
|
||||||
|
|
||||||
dxy0 /= roundUnit;
|
dxy0 /= roundUnit;
|
||||||
dxy0.X = MathF.Round(dxy0.X);
|
dxy0 = new(MathF.Round(dxy0.X), MathF.Round(dxy0.Y));
|
||||||
dxy0.Y = MathF.Round(dxy0.Y);
|
|
||||||
dxy0 *= roundUnit;
|
dxy0 *= roundUnit;
|
||||||
|
|
||||||
dxy0.Y += shiftDown;
|
dxy0.Y += shiftDown;
|
||||||
|
|
|
||||||
|
|
@ -342,9 +342,7 @@ public sealed class SingleFontChooserDialog : IDisposable
|
||||||
{
|
{
|
||||||
this.fontHandle ??= this.selectedFont.CreateFontHandle(
|
this.fontHandle ??= this.selectedFont.CreateFontHandle(
|
||||||
this.atlas,
|
this.atlas,
|
||||||
tk =>
|
tk => tk.OnPreBuild(e => e.SetFontScaleMode(e.Font, FontScaleMode.UndoGlobalScale)));
|
||||||
tk.OnPreBuild(e => e.IgnoreGlobalScale(e.Font))
|
|
||||||
.OnPostBuild(e => e.Font.AdjustGlyphMetrics(1f / e.Scale)));
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
@ -837,7 +835,7 @@ public sealed class SingleFontChooserDialog : IDisposable
|
||||||
var changed = false;
|
var changed = false;
|
||||||
|
|
||||||
if (!ImGui.BeginTable("##advancedOptions", 4))
|
if (!ImGui.BeginTable("##advancedOptions", 4))
|
||||||
return changed;
|
return false;
|
||||||
|
|
||||||
var labelWidth = ImGui.CalcTextSize("Letter Spacing:").X;
|
var labelWidth = ImGui.CalcTextSize("Letter Spacing:").X;
|
||||||
labelWidth = Math.Max(labelWidth, ImGui.CalcTextSize("Offset:").X);
|
labelWidth = Math.Max(labelWidth, ImGui.CalcTextSize("Offset:").X);
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,20 @@ namespace Dalamud.Interface.Internal.Windows.Data.Widgets;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
{
|
{
|
||||||
|
private static readonly string[] FontScaleModes =
|
||||||
|
{
|
||||||
|
nameof(FontScaleMode.Default),
|
||||||
|
nameof(FontScaleMode.SkipHandling),
|
||||||
|
nameof(FontScaleMode.UndoGlobalScale),
|
||||||
|
};
|
||||||
|
|
||||||
private ImVectorWrapper<byte> testStringBuffer;
|
private ImVectorWrapper<byte> testStringBuffer;
|
||||||
private IFontAtlas? privateAtlas;
|
private IFontAtlas? privateAtlas;
|
||||||
private SingleFontSpec fontSpec = new() { FontId = DalamudDefaultFontAndFamilyId.Instance };
|
private SingleFontSpec fontSpec = new() { FontId = DalamudDefaultFontAndFamilyId.Instance };
|
||||||
private IFontHandle? fontDialogHandle;
|
private IFontHandle? fontDialogHandle;
|
||||||
private IReadOnlyDictionary<GameFontFamily, (GameFontStyle Size, Lazy<IFontHandle> Handle)[]>? fontHandles;
|
private IReadOnlyDictionary<GameFontFamily, (GameFontStyle Size, Lazy<IFontHandle> Handle)[]>? fontHandles;
|
||||||
private bool useGlobalScale;
|
private bool atlasScaleMode = true;
|
||||||
|
private int fontScaleMode = (int)FontScaleMode.UndoGlobalScale;
|
||||||
private bool useWordWrap;
|
private bool useWordWrap;
|
||||||
private bool useItalic;
|
private bool useItalic;
|
||||||
private bool useBold;
|
private bool useBold;
|
||||||
|
|
@ -52,12 +60,14 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
public unsafe void Draw()
|
public unsafe void Draw()
|
||||||
{
|
{
|
||||||
ImGui.AlignTextToFramePadding();
|
ImGui.AlignTextToFramePadding();
|
||||||
fixed (byte* labelPtr = "Global Scale"u8)
|
if (ImGui.Combo("Global Scale per Font", ref this.fontScaleMode, FontScaleModes, FontScaleModes.Length))
|
||||||
|
this.ClearAtlas();
|
||||||
|
fixed (byte* labelPtr = "Global Scale for Atlas"u8)
|
||||||
{
|
{
|
||||||
var v = (byte)(this.useGlobalScale ? 1 : 0);
|
var v = (byte)(this.atlasScaleMode ? 1 : 0);
|
||||||
if (ImGuiNative.igCheckbox(labelPtr, &v) != 0)
|
if (ImGuiNative.igCheckbox(labelPtr, &v) != 0)
|
||||||
{
|
{
|
||||||
this.useGlobalScale = v != 0;
|
this.atlasScaleMode = v != 0;
|
||||||
this.ClearAtlas();
|
this.ClearAtlas();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +134,7 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
$"{nameof(GamePrebakedFontsTestWidget)}:EditorFont",
|
$"{nameof(GamePrebakedFontsTestWidget)}:EditorFont",
|
||||||
FontAtlasAutoRebuildMode.Async));
|
FontAtlasAutoRebuildMode.Async));
|
||||||
fcd.SelectedFont = this.fontSpec;
|
fcd.SelectedFont = this.fontSpec;
|
||||||
fcd.IgnorePreviewGlobalScale = !this.useGlobalScale;
|
fcd.IgnorePreviewGlobalScale = !this.atlasScaleMode;
|
||||||
Service<InterfaceManager>.Get().Draw += fcd.Draw;
|
Service<InterfaceManager>.Get().Draw += fcd.Draw;
|
||||||
fcd.ResultTask.ContinueWith(
|
fcd.ResultTask.ContinueWith(
|
||||||
r => Service<Framework>.Get().RunOnFrameworkThread(
|
r => Service<Framework>.Get().RunOnFrameworkThread(
|
||||||
|
|
@ -148,12 +158,14 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
Service<FontAtlasFactory>.Get().CreateFontAtlas(
|
Service<FontAtlasFactory>.Get().CreateFontAtlas(
|
||||||
nameof(GamePrebakedFontsTestWidget),
|
nameof(GamePrebakedFontsTestWidget),
|
||||||
FontAtlasAutoRebuildMode.Async,
|
FontAtlasAutoRebuildMode.Async,
|
||||||
this.useGlobalScale);
|
this.atlasScaleMode);
|
||||||
this.fontDialogHandle ??= this.fontSpec.CreateFontHandle(this.privateAtlas);
|
this.fontDialogHandle ??= this.fontSpec.CreateFontHandle(
|
||||||
|
this.privateAtlas,
|
||||||
|
e => e.OnPreBuild(tk => tk.SetFontScaleMode(tk.Font, (FontScaleMode)this.fontScaleMode)));
|
||||||
|
|
||||||
fixed (byte* labelPtr = "Test Input"u8)
|
fixed (byte* labelPtr = "Test Input"u8)
|
||||||
{
|
{
|
||||||
if (!this.useGlobalScale)
|
if (!this.atlasScaleMode)
|
||||||
ImGuiNative.igSetWindowFontScale(1 / ImGuiHelpers.GlobalScale);
|
ImGuiNative.igSetWindowFontScale(1 / ImGuiHelpers.GlobalScale);
|
||||||
using (this.fontDialogHandle.Push())
|
using (this.fontDialogHandle.Push())
|
||||||
{
|
{
|
||||||
|
|
@ -180,7 +192,7 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!this.useGlobalScale)
|
if (!this.atlasScaleMode)
|
||||||
ImGuiNative.igSetWindowFontScale(1);
|
ImGuiNative.igSetWindowFontScale(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -192,17 +204,29 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
.ToImmutableDictionary(
|
.ToImmutableDictionary(
|
||||||
x => x.Key,
|
x => x.Key,
|
||||||
x => x.Select(
|
x => x.Select(
|
||||||
y => (y, new Lazy<IFontHandle>(
|
y =>
|
||||||
() => this.useMinimumBuild
|
{
|
||||||
? this.privateAtlas.NewDelegateFontHandle(
|
var range = Encoding.UTF8.GetString(this.testStringBuffer.DataSpan).ToGlyphRange();
|
||||||
e =>
|
|
||||||
e.OnPreBuild(
|
Lazy<IFontHandle> l;
|
||||||
tk => tk.AddGameGlyphs(
|
if (this.useMinimumBuild
|
||||||
y,
|
|| (this.atlasScaleMode && this.fontScaleMode != (int)FontScaleMode.Default))
|
||||||
Encoding.UTF8.GetString(
|
{
|
||||||
this.testStringBuffer.DataSpan).ToGlyphRange(),
|
l = new(
|
||||||
default)))
|
() => this.privateAtlas!.NewDelegateFontHandle(
|
||||||
: this.privateAtlas.NewGameFontHandle(y))))
|
e =>
|
||||||
|
e.OnPreBuild(
|
||||||
|
tk => tk.SetFontScaleMode(
|
||||||
|
tk.AddGameGlyphs(y, range, default),
|
||||||
|
(FontScaleMode)this.fontScaleMode))));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l = new(() => this.privateAtlas!.NewGameFontHandle(y));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (y, l);
|
||||||
|
})
|
||||||
.ToArray());
|
.ToArray());
|
||||||
|
|
||||||
var offsetX = ImGui.CalcTextSize("99.9pt").X + (ImGui.GetStyle().FramePadding.X * 2);
|
var offsetX = ImGui.CalcTextSize("99.9pt").X + (ImGui.GetStyle().FramePadding.X * 2);
|
||||||
|
|
@ -230,7 +254,7 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!this.useGlobalScale)
|
if (!this.atlasScaleMode)
|
||||||
ImGuiNative.igSetWindowFontScale(1 / ImGuiHelpers.GlobalScale);
|
ImGuiNative.igSetWindowFontScale(1 / ImGuiHelpers.GlobalScale);
|
||||||
if (counter++ % 2 == 0)
|
if (counter++ % 2 == 0)
|
||||||
{
|
{
|
||||||
|
|
@ -251,8 +275,8 @@ internal class GamePrebakedFontsTestWidget : IDataWindowWidget, IDisposable
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
ImGuiNative.igPopTextWrapPos();
|
|
||||||
ImGuiNative.igSetWindowFontScale(1);
|
ImGuiNative.igSetWindowFontScale(1);
|
||||||
|
ImGuiNative.igPopTextWrapPos();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
33
Dalamud/Interface/ManagedFontAtlas/FontScaleMode.cs
Normal file
33
Dalamud/Interface/ManagedFontAtlas/FontScaleMode.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
using Dalamud.Interface.Utility;
|
||||||
|
|
||||||
|
using ImGuiNET;
|
||||||
|
|
||||||
|
namespace Dalamud.Interface.ManagedFontAtlas;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Specifies how should global font scale affect a font.
|
||||||
|
/// </summary>
|
||||||
|
public enum FontScaleMode
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Do the default handling. Dalamud will load the sufficienty large font that will accomodate the global scale,
|
||||||
|
/// and stretch the loaded glyphs so that they look pixel-perfect after applying global scale on drawing.
|
||||||
|
/// Note that bitmap fonts and game fonts will always look blurry if they're not in their original sizes.
|
||||||
|
/// </summary>
|
||||||
|
Default,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Do nothing with the font. Dalamud will load the font with the size that is exactly as specified.
|
||||||
|
/// On drawing, the font will look blurry due to stretching.
|
||||||
|
/// Intended for use with custom scale handling.
|
||||||
|
/// </summary>
|
||||||
|
SkipHandling,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Stretch the glyphs of the loaded font by the inverse of the global scale.
|
||||||
|
/// On drawing, the font will always render exactly as the requested size without blurring, as long as
|
||||||
|
/// <see cref="ImGuiHelpers.GlobalScale"/> and <see cref="ImGui.SetWindowFontScale"/> do not affect the scale any
|
||||||
|
/// further. Note that bitmap fonts and game fonts will always look blurry if they're not in their original sizes.
|
||||||
|
/// </summary>
|
||||||
|
UndoGlobalScale,
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Dalamud.Interface.Internal;
|
using Dalamud.Interface.Internal;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
|
@ -10,12 +11,13 @@ namespace Dalamud.Interface.ManagedFontAtlas;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public interface IFontAtlasBuildToolkitPostBuild : IFontAtlasBuildToolkit
|
public interface IFontAtlasBuildToolkitPostBuild : IFontAtlasBuildToolkit
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.IsGlobalScaleIgnored"/>
|
||||||
/// Gets whether global scaling is ignored for the given font.
|
[Obsolete($"Use {nameof(this.GetFontScaleMode)}")]
|
||||||
/// </summary>
|
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||||
/// <param name="fontPtr">The font.</param>
|
bool IsGlobalScaleIgnored(ImFontPtr fontPtr) => this.GetFontScaleMode(fontPtr) == FontScaleMode.UndoGlobalScale;
|
||||||
/// <returns>True if ignored.</returns>
|
|
||||||
bool IsGlobalScaleIgnored(ImFontPtr fontPtr);
|
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.GetFontScaleMode"/>
|
||||||
|
FontScaleMode GetFontScaleMode(ImFontPtr fontPtr);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Stores a texture to be managed with the atlas.
|
/// Stores a texture to be managed with the atlas.
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using System.Runtime.InteropServices;
|
||||||
using Dalamud.Interface.FontIdentifier;
|
using Dalamud.Interface.FontIdentifier;
|
||||||
using Dalamud.Interface.GameFonts;
|
using Dalamud.Interface.GameFonts;
|
||||||
using Dalamud.Interface.Utility;
|
using Dalamud.Interface.Utility;
|
||||||
|
using Dalamud.Utility;
|
||||||
|
|
||||||
using ImGuiNET;
|
using ImGuiNET;
|
||||||
|
|
||||||
|
|
@ -45,14 +46,37 @@ public interface IFontAtlasBuildToolkitPreBuild : IFontAtlasBuildToolkit
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fontPtr">The font.</param>
|
/// <param name="fontPtr">The font.</param>
|
||||||
/// <returns>Same <see cref="ImFontPtr"/> with <paramref name="fontPtr"/>.</returns>
|
/// <returns>Same <see cref="ImFontPtr"/> with <paramref name="fontPtr"/>.</returns>
|
||||||
ImFontPtr IgnoreGlobalScale(ImFontPtr fontPtr);
|
[Obsolete(
|
||||||
|
$"Use {nameof(this.SetFontScaleMode)} with {nameof(FontScaleMode)}.{nameof(FontScaleMode.UndoGlobalScale)}")]
|
||||||
|
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||||
|
ImFontPtr IgnoreGlobalScale(ImFontPtr fontPtr) => this.SetFontScaleMode(fontPtr, FontScaleMode.UndoGlobalScale);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether global scaling is ignored for the given font.
|
/// Gets whether global scaling is ignored for the given font.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="fontPtr">The font.</param>
|
/// <param name="fontPtr">The font.</param>
|
||||||
/// <returns>True if ignored.</returns>
|
/// <returns>True if ignored.</returns>
|
||||||
bool IsGlobalScaleIgnored(ImFontPtr fontPtr);
|
[Obsolete($"Use {nameof(this.GetFontScaleMode)}")]
|
||||||
|
[Api10ToDo(Api10ToDoAttribute.DeleteCompatBehavior)]
|
||||||
|
bool IsGlobalScaleIgnored(ImFontPtr fontPtr) => this.GetFontScaleMode(fontPtr) == FontScaleMode.UndoGlobalScale;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets the scaling mode for the given font.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fontPtr">The font, returned from <see cref="AddFontFromFile"/> and alike.
|
||||||
|
/// Note that <see cref="IFontAtlasBuildToolkit.Font"/> property is not guaranteed to be automatically updated upon
|
||||||
|
/// calling font adding functions. Pass the return value from font adding functions, not
|
||||||
|
/// <see cref="IFontAtlasBuildToolkit.Font"/> property.</param>
|
||||||
|
/// <param name="mode">The scaling mode.</param>
|
||||||
|
/// <returns><paramref name="fontPtr"/>.</returns>
|
||||||
|
ImFontPtr SetFontScaleMode(ImFontPtr fontPtr, FontScaleMode mode);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the scaling mode for the given font.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fontPtr">The font.</param>
|
||||||
|
/// <returns>The scaling mode.</returns>
|
||||||
|
FontScaleMode GetFontScaleMode(ImFontPtr fontPtr);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers a function to be run after build.
|
/// Registers a function to be run after build.
|
||||||
|
|
|
||||||
|
|
@ -83,9 +83,9 @@ internal sealed partial class FontAtlasFactory
|
||||||
public ImVectorWrapper<ImFontPtr> Fonts => this.data.Fonts;
|
public ImVectorWrapper<ImFontPtr> Fonts => this.data.Fonts;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the list of fonts to ignore global scale.
|
/// Gets the font scale modes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public List<ImFontPtr> GlobalScaleExclusions { get; } = new();
|
private Dictionary<ImFontPtr, FontScaleMode> FontScaleModes { get; } = new();
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public void Dispose() => this.disposeAfterBuild.Dispose();
|
public void Dispose() => this.disposeAfterBuild.Dispose();
|
||||||
|
|
@ -151,15 +151,15 @@ internal sealed partial class FontAtlasFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public ImFontPtr IgnoreGlobalScale(ImFontPtr fontPtr)
|
public ImFontPtr SetFontScaleMode(ImFontPtr fontPtr, FontScaleMode scaleMode)
|
||||||
{
|
{
|
||||||
this.GlobalScaleExclusions.Add(fontPtr);
|
this.FontScaleModes[fontPtr] = scaleMode;
|
||||||
return fontPtr;
|
return fontPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.IsGlobalScaleIgnored"/>
|
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.GetFontScaleMode"/>
|
||||||
public bool IsGlobalScaleIgnored(ImFontPtr fontPtr) =>
|
public FontScaleMode GetFontScaleMode(ImFontPtr fontPtr) =>
|
||||||
this.GlobalScaleExclusions.Contains(fontPtr);
|
this.FontScaleModes.GetValueOrDefault(fontPtr, FontScaleMode.Default);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public int StoreTexture(IDalamudTextureWrap textureWrap, bool disposeOnError) =>
|
public int StoreTexture(IDalamudTextureWrap textureWrap, bool disposeOnError) =>
|
||||||
|
|
@ -496,17 +496,17 @@ internal sealed partial class FontAtlasFactory
|
||||||
var configData = this.data.ConfigData;
|
var configData = this.data.ConfigData;
|
||||||
foreach (ref var config in configData.DataSpan)
|
foreach (ref var config in configData.DataSpan)
|
||||||
{
|
{
|
||||||
if (this.GlobalScaleExclusions.Contains(new(config.DstFont)))
|
if (this.GetFontScaleMode(config.DstFont) != FontScaleMode.Default)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
config.SizePixels *= this.Scale;
|
config.SizePixels *= this.Scale;
|
||||||
|
|
||||||
config.GlyphMaxAdvanceX *= this.Scale;
|
config.GlyphMaxAdvanceX *= this.Scale;
|
||||||
if (float.IsInfinity(config.GlyphMaxAdvanceX))
|
if (float.IsInfinity(config.GlyphMaxAdvanceX) || float.IsNaN(config.GlyphMaxAdvanceX))
|
||||||
config.GlyphMaxAdvanceX = config.GlyphMaxAdvanceX > 0 ? float.MaxValue : -float.MaxValue;
|
config.GlyphMaxAdvanceX = config.GlyphMaxAdvanceX > 0 ? float.MaxValue : -float.MaxValue;
|
||||||
|
|
||||||
config.GlyphMinAdvanceX *= this.Scale;
|
config.GlyphMinAdvanceX *= this.Scale;
|
||||||
if (float.IsInfinity(config.GlyphMinAdvanceX))
|
if (float.IsInfinity(config.GlyphMinAdvanceX) || float.IsNaN(config.GlyphMinAdvanceX))
|
||||||
config.GlyphMinAdvanceX = config.GlyphMinAdvanceX > 0 ? float.MaxValue : -float.MaxValue;
|
config.GlyphMinAdvanceX = config.GlyphMinAdvanceX > 0 ? float.MaxValue : -float.MaxValue;
|
||||||
|
|
||||||
config.GlyphOffset *= this.Scale;
|
config.GlyphOffset *= this.Scale;
|
||||||
|
|
@ -536,7 +536,7 @@ internal sealed partial class FontAtlasFactory
|
||||||
var scale = this.Scale;
|
var scale = this.Scale;
|
||||||
foreach (ref var font in this.Fonts.DataSpan)
|
foreach (ref var font in this.Fonts.DataSpan)
|
||||||
{
|
{
|
||||||
if (!this.GlobalScaleExclusions.Contains(font))
|
if (this.GetFontScaleMode(font) != FontScaleMode.SkipHandling)
|
||||||
font.AdjustGlyphMetrics(1 / scale, 1 / scale);
|
font.AdjustGlyphMetrics(1 / scale, 1 / scale);
|
||||||
|
|
||||||
foreach (var c in FallbackCodepoints)
|
foreach (var c in FallbackCodepoints)
|
||||||
|
|
|
||||||
|
|
@ -345,17 +345,36 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
{
|
{
|
||||||
foreach (var (font, style, ranges) in this.attachments)
|
foreach (var (font, style, ranges) in this.attachments)
|
||||||
{
|
{
|
||||||
var effectiveStyle =
|
|
||||||
toolkitPreBuild.IsGlobalScaleIgnored(font)
|
|
||||||
? style.Scale(1 / toolkitPreBuild.Scale)
|
|
||||||
: style;
|
|
||||||
if (!this.fonts.TryGetValue(style, out var plan))
|
if (!this.fonts.TryGetValue(style, out var plan))
|
||||||
{
|
{
|
||||||
plan = new(
|
switch (toolkitPreBuild.GetFontScaleMode(font))
|
||||||
effectiveStyle,
|
{
|
||||||
toolkitPreBuild.Scale,
|
case FontScaleMode.Default:
|
||||||
this.handleManager.GameFontTextureProvider,
|
default:
|
||||||
this.CreateTemplateFont(toolkitPreBuild, style.SizePx));
|
plan = new(
|
||||||
|
style,
|
||||||
|
toolkitPreBuild.Scale,
|
||||||
|
this.handleManager.GameFontTextureProvider,
|
||||||
|
this.CreateTemplateFont(toolkitPreBuild, style.SizePx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FontScaleMode.SkipHandling:
|
||||||
|
plan = new(
|
||||||
|
style,
|
||||||
|
1f,
|
||||||
|
this.handleManager.GameFontTextureProvider,
|
||||||
|
this.CreateTemplateFont(toolkitPreBuild, style.SizePx));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FontScaleMode.UndoGlobalScale:
|
||||||
|
plan = new(
|
||||||
|
style.Scale(1 / toolkitPreBuild.Scale),
|
||||||
|
toolkitPreBuild.Scale,
|
||||||
|
this.handleManager.GameFontTextureProvider,
|
||||||
|
this.CreateTemplateFont(toolkitPreBuild, style.SizePx));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
this.fonts[style] = plan;
|
this.fonts[style] = plan;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -620,15 +639,14 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
public unsafe void CopyGlyphsToRanges(IFontAtlasBuildToolkitPostBuild toolkitPostBuild)
|
public unsafe void CopyGlyphsToRanges(IFontAtlasBuildToolkitPostBuild toolkitPostBuild)
|
||||||
{
|
{
|
||||||
var scale = this.Style.SizePt / this.Fdt.FontHeader.Size;
|
var scale = this.Style.SizePt / this.Fdt.FontHeader.Size;
|
||||||
var atlasScale = toolkitPostBuild.Scale;
|
|
||||||
var round = 1 / atlasScale;
|
|
||||||
|
|
||||||
foreach (var (font, rangeBits) in this.Ranges)
|
foreach (var (font, rangeBits) in this.Ranges)
|
||||||
{
|
{
|
||||||
if (font.NativePtr == this.FullRangeFont.NativePtr)
|
if (font.NativePtr == this.FullRangeFont.NativePtr)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var noGlobalScale = toolkitPostBuild.IsGlobalScaleIgnored(font);
|
var fontScaleMode = toolkitPostBuild.GetFontScaleMode(font);
|
||||||
|
var round = fontScaleMode == FontScaleMode.SkipHandling ? 1 : 1 / toolkitPostBuild.Scale;
|
||||||
|
|
||||||
var lookup = font.IndexLookupWrapped();
|
var lookup = font.IndexLookupWrapped();
|
||||||
var glyphs = font.GlyphsWrapped();
|
var glyphs = font.GlyphsWrapped();
|
||||||
|
|
@ -649,7 +667,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
|
|
||||||
ref var g = ref glyphs[glyphIndex];
|
ref var g = ref glyphs[glyphIndex];
|
||||||
g = sourceGlyph;
|
g = sourceGlyph;
|
||||||
if (noGlobalScale)
|
if (fontScaleMode == FontScaleMode.SkipHandling)
|
||||||
{
|
{
|
||||||
g.XY *= scale;
|
g.XY *= scale;
|
||||||
g.AdvanceX *= scale;
|
g.AdvanceX *= scale;
|
||||||
|
|
@ -673,7 +691,7 @@ internal class GamePrebakedFontHandle : FontHandle
|
||||||
continue;
|
continue;
|
||||||
if (!rangeBits[leftInt] || !rangeBits[rightInt])
|
if (!rangeBits[leftInt] || !rangeBits[rightInt])
|
||||||
continue;
|
continue;
|
||||||
if (noGlobalScale)
|
if (fontScaleMode == FontScaleMode.SkipHandling)
|
||||||
{
|
{
|
||||||
font.AddKerningPair((ushort)leftInt, (ushort)rightInt, k.RightOffset * scale);
|
font.AddKerningPair((ushort)leftInt, (ushort)rightInt, k.RightOffset * scale);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue