diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
index 46fb3f63d..fdef499dd 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/FontAtlasFactory.BuildToolkit.cs
@@ -430,7 +430,7 @@ internal sealed partial class FontAtlasFactory
foreach (ref var font in this.Fonts.DataSpan)
{
if (!this.GlobalScaleExclusions.Contains(font))
- font.AdjustGlyphMetrics(1 / scale, scale);
+ font.AdjustGlyphMetrics(1 / scale, 1 / scale);
foreach (var c in FallbackCodepoints)
{
diff --git a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
index 1ac6fdbce..99c817a91 100644
--- a/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
+++ b/Dalamud/Interface/ManagedFontAtlas/Internals/GamePrebakedFontHandle.cs
@@ -369,8 +369,8 @@ internal class GamePrebakedFontHandle : IFontHandle.IInternal
this.PatchFontMetricsIfNecessary(style, font, toolkitPostBuild.Scale);
plan.SetFullRangeFontGlyphs(toolkitPostBuild, allTexFiles, allTextureIndices, pixels8Array, widths);
- plan.PostProcessFullRangeFont();
- plan.CopyGlyphsToRanges();
+ plan.CopyGlyphsToRanges(toolkitPostBuild);
+ plan.PostProcessFullRangeFont(toolkitPostBuild.Scale);
}
catch (Exception e)
{
@@ -543,17 +543,43 @@ internal class GamePrebakedFontHandle : IFontHandle.IInternal
}
}
- public unsafe void PostProcessFullRangeFont()
+ public unsafe void PostProcessFullRangeFont(float atlasScale)
{
+ var round = 1 / atlasScale;
+ var pfrf = this.FullRangeFont.NativePtr;
+ ref var frf = ref *pfrf;
+
+ frf.FontSize = MathF.Round(frf.FontSize / round) * round;
+ frf.Ascent = MathF.Round(frf.Ascent / round) * round;
+ frf.Descent = MathF.Round(frf.Descent / round) * round;
+
var scale = this.Style.SizePt / this.Fdt.FontHeader.Size;
foreach (ref var g in this.FullRangeFont.GlyphsWrapped().DataSpan)
{
- g.XY *= scale;
- g.AdvanceX *= scale;
+ var w = (g.X1 - g.X0) * scale;
+ var h = (g.Y1 - g.Y0) * scale;
+ g.X0 = MathF.Round((g.X0 * scale) / round) * round;
+ g.Y0 = MathF.Round((g.Y0 * scale) / round) * round;
+ g.X1 = g.X0 + w;
+ g.Y1 = g.Y0 + h;
+ g.AdvanceX = MathF.Round((g.AdvanceX * scale) / round) * round;
+ }
+
+ var fullRange = this.Ranges[this.FullRangeFont];
+ foreach (ref var k in this.Fdt.PairAdjustments)
+ {
+ var (leftInt, rightInt) = (k.LeftInt, k.RightInt);
+ if (leftInt > char.MaxValue || rightInt > char.MaxValue)
+ continue;
+ if (!fullRange[leftInt] || !fullRange[rightInt])
+ continue;
+ ImGuiNative.ImFont_AddKerningPair(
+ pfrf,
+ (ushort)leftInt,
+ (ushort)rightInt,
+ MathF.Round((k.RightOffset * scale) / round) * round);
}
- var pfrf = this.FullRangeFont.NativePtr;
- ref var frf = ref *pfrf;
pfrf->FallbackGlyph = null;
ImGuiNative.ImFont_BuildLookupTable(pfrf);
@@ -571,13 +597,19 @@ internal class GamePrebakedFontHandle : IFontHandle.IInternal
}
}
- public unsafe void CopyGlyphsToRanges()
+ public unsafe void CopyGlyphsToRanges(IFontAtlasBuildToolkitPostBuild toolkitPostBuild)
{
+ var scale = this.Style.SizePt / this.Fdt.FontHeader.Size;
+ var atlasScale = toolkitPostBuild.Scale;
+ var round = 1 / atlasScale;
+
foreach (var (font, rangeBits) in this.Ranges)
{
if (font.NativePtr == this.FullRangeFont.NativePtr)
continue;
+ var noGlobalScale = toolkitPostBuild.IsGlobalScaleIgnored(font);
+
var lookup = font.IndexLookupWrapped();
var glyphs = font.GlyphsWrapped();
foreach (ref var sourceGlyph in this.FullRangeFont.GlyphsWrapped().DataSpan)
@@ -590,9 +622,48 @@ internal class GamePrebakedFontHandle : IFontHandle.IInternal
glyphIndex = lookup[sourceGlyph.Codepoint];
if (glyphIndex == ushort.MaxValue)
- glyphs.Add(sourceGlyph);
+ {
+ glyphIndex = (ushort)glyphs.Length;
+ glyphs.Add(default);
+ }
+
+ ref var g = ref glyphs[glyphIndex];
+ g = sourceGlyph;
+ if (noGlobalScale)
+ {
+ g.XY *= scale;
+ g.AdvanceX *= scale;
+ }
else
- glyphs[glyphIndex] = sourceGlyph;
+ {
+ var w = (g.X1 - g.X0) * scale;
+ var h = (g.Y1 - g.Y0) * scale;
+ g.X0 = MathF.Round((g.X0 * scale) / round) * round;
+ g.Y0 = MathF.Round((g.Y0 * scale) / round) * round;
+ g.X1 = g.X0 + w;
+ g.Y1 = g.Y0 + h;
+ g.AdvanceX = MathF.Round((g.AdvanceX * scale) / round) * round;
+ }
+ }
+
+ foreach (ref var k in this.Fdt.PairAdjustments)
+ {
+ var (leftInt, rightInt) = (k.LeftInt, k.RightInt);
+ if (leftInt > char.MaxValue || rightInt > char.MaxValue)
+ continue;
+ if (!rangeBits[leftInt] || !rangeBits[rightInt])
+ continue;
+ if (noGlobalScale)
+ {
+ font.AddKerningPair((ushort)leftInt, (ushort)rightInt, k.RightOffset * scale);
+ }
+ else
+ {
+ font.AddKerningPair(
+ (ushort)leftInt,
+ (ushort)rightInt,
+ MathF.Round((k.RightOffset * scale) / round) * round);
+ }
}
font.NativePtr->FallbackGlyph = null;
diff --git a/Dalamud/Interface/Utility/ImGuiHelpers.cs b/Dalamud/Interface/Utility/ImGuiHelpers.cs
index ed6ad1dfe..8ba103593 100644
--- a/Dalamud/Interface/Utility/ImGuiHelpers.cs
+++ b/Dalamud/Interface/Utility/ImGuiHelpers.cs
@@ -202,7 +202,7 @@ public static class ImGuiHelpers
/// If a positive number is given, numbers will be rounded to this.
public static unsafe void AdjustGlyphMetrics(this ImFontPtr fontPtr, float scale, float round = 0f)
{
- Func rounder = round > 0 ? x => MathF.Round(x * round) / round : x => x;
+ Func rounder = round > 0 ? x => MathF.Round(x / round) * round : x => x;
var font = fontPtr.NativePtr;
font->FontSize = rounder(font->FontSize * scale);