mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
Better rounding
This commit is contained in:
parent
2bfddaae16
commit
f172ee2308
3 changed files with 83 additions and 12 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ public static class ImGuiHelpers
|
|||
/// <param name="round">If a positive number is given, numbers will be rounded to this.</param>
|
||||
public static unsafe void AdjustGlyphMetrics(this ImFontPtr fontPtr, float scale, float round = 0f)
|
||||
{
|
||||
Func<float, float> rounder = round > 0 ? x => MathF.Round(x * round) / round : x => x;
|
||||
Func<float, float> rounder = round > 0 ? x => MathF.Round(x / round) * round : x => x;
|
||||
|
||||
var font = fontPtr.NativePtr;
|
||||
font->FontSize = rounder(font->FontSize * scale);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue