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:
srkizer 2024-02-18 23:08:07 +09:00 committed by GitHub
parent 7dc99c9307
commit 2d8b71c647
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 166 additions and 66 deletions

View file

@ -83,9 +83,9 @@ internal sealed partial class FontAtlasFactory
public ImVectorWrapper<ImFontPtr> Fonts => this.data.Fonts;
/// <summary>
/// Gets the list of fonts to ignore global scale.
/// Gets the font scale modes.
/// </summary>
public List<ImFontPtr> GlobalScaleExclusions { get; } = new();
private Dictionary<ImFontPtr, FontScaleMode> FontScaleModes { get; } = new();
/// <inheritdoc/>
public void Dispose() => this.disposeAfterBuild.Dispose();
@ -151,15 +151,15 @@ internal sealed partial class FontAtlasFactory
}
/// <inheritdoc/>
public ImFontPtr IgnoreGlobalScale(ImFontPtr fontPtr)
public ImFontPtr SetFontScaleMode(ImFontPtr fontPtr, FontScaleMode scaleMode)
{
this.GlobalScaleExclusions.Add(fontPtr);
this.FontScaleModes[fontPtr] = scaleMode;
return fontPtr;
}
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.IsGlobalScaleIgnored"/>
public bool IsGlobalScaleIgnored(ImFontPtr fontPtr) =>
this.GlobalScaleExclusions.Contains(fontPtr);
/// <inheritdoc cref="IFontAtlasBuildToolkitPreBuild.GetFontScaleMode"/>
public FontScaleMode GetFontScaleMode(ImFontPtr fontPtr) =>
this.FontScaleModes.GetValueOrDefault(fontPtr, FontScaleMode.Default);
/// <inheritdoc/>
public int StoreTexture(IDalamudTextureWrap textureWrap, bool disposeOnError) =>
@ -496,17 +496,17 @@ internal sealed partial class FontAtlasFactory
var configData = this.data.ConfigData;
foreach (ref var config in configData.DataSpan)
{
if (this.GlobalScaleExclusions.Contains(new(config.DstFont)))
if (this.GetFontScaleMode(config.DstFont) != FontScaleMode.Default)
continue;
config.SizePixels *= 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.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.GlyphOffset *= this.Scale;
@ -536,7 +536,7 @@ internal sealed partial class FontAtlasFactory
var scale = this.Scale;
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);
foreach (var c in FallbackCodepoints)

View file

@ -345,17 +345,36 @@ internal class GamePrebakedFontHandle : FontHandle
{
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))
{
plan = new(
effectiveStyle,
toolkitPreBuild.Scale,
this.handleManager.GameFontTextureProvider,
this.CreateTemplateFont(toolkitPreBuild, style.SizePx));
switch (toolkitPreBuild.GetFontScaleMode(font))
{
case FontScaleMode.Default:
default:
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;
}
@ -620,15 +639,14 @@ internal class GamePrebakedFontHandle : FontHandle
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 fontScaleMode = toolkitPostBuild.GetFontScaleMode(font);
var round = fontScaleMode == FontScaleMode.SkipHandling ? 1 : 1 / toolkitPostBuild.Scale;
var lookup = font.IndexLookupWrapped();
var glyphs = font.GlyphsWrapped();
@ -649,7 +667,7 @@ internal class GamePrebakedFontHandle : FontHandle
ref var g = ref glyphs[glyphIndex];
g = sourceGlyph;
if (noGlobalScale)
if (fontScaleMode == FontScaleMode.SkipHandling)
{
g.XY *= scale;
g.AdvanceX *= scale;
@ -673,7 +691,7 @@ internal class GamePrebakedFontHandle : FontHandle
continue;
if (!rangeBits[leftInt] || !rangeBits[rightInt])
continue;
if (noGlobalScale)
if (fontScaleMode == FontScaleMode.SkipHandling)
{
font.AddKerningPair((ushort)leftInt, (ushort)rightInt, k.RightOffset * scale);
}