Merge branch 'net5' of ssh://github.com/goatcorp/Dalamud into net5

This commit is contained in:
goaaats 2022-04-15 21:32:54 +02:00
commit 82c8030ce0
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
3 changed files with 87 additions and 37 deletions

View file

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Numerics; using System.Numerics;
using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Dalamud.Configuration.Internal; using Dalamud.Configuration.Internal;
@ -229,7 +230,10 @@ namespace Dalamud.Interface.GameFonts
} }
if (needRebuild) if (needRebuild)
{
Log.Information("[GameFontManager] Calling RebuildFonts because {0} has been requested.", style.ToString());
this.interfaceManager.RebuildFonts(); this.interfaceManager.RebuildFonts();
}
return new(this, style); return new(this, style);
} }
@ -287,7 +291,8 @@ namespace Dalamud.Interface.GameFonts
/// <summary> /// <summary>
/// Build fonts before plugins do something more. To be called from InterfaceManager. /// Build fonts before plugins do something more. To be called from InterfaceManager.
/// </summary> /// </summary>
public void BuildFonts() /// <param name="forceMinSize">Whether to load fonts in minimum sizes.</param>
public void BuildFonts(bool forceMinSize)
{ {
unsafe unsafe
{ {
@ -305,7 +310,7 @@ namespace Dalamud.Interface.GameFonts
{ {
var rectIds = this.glyphRectIds[style] = new(); var rectIds = this.glyphRectIds[style] = new();
var fdt = this.fdts[(int)style.FamilyAndSize]; var fdt = this.fdts[(int)(forceMinSize ? style.FamilyWithMinimumSize : style.FamilyAndSize)];
if (fdt == null) if (fdt == null)
continue; continue;
@ -318,7 +323,7 @@ namespace Dalamud.Interface.GameFonts
if (c < 32 || c >= 0xFFFF) if (c < 32 || c >= 0xFFFF)
continue; continue;
var widthAdjustment = style.CalculateWidthAdjustment(fdt, glyph); var widthAdjustment = style.CalculateBaseWidthAdjustment(fdt, glyph);
rectIds[c] = Tuple.Create( rectIds[c] = Tuple.Create(
io.Fonts.AddCustomRectFontGlyph( io.Fonts.AddCustomRectFontGlyph(
font, font,
@ -338,7 +343,8 @@ namespace Dalamud.Interface.GameFonts
/// <summary> /// <summary>
/// Post-build fonts before plugins do something more. To be called from InterfaceManager. /// Post-build fonts before plugins do something more. To be called from InterfaceManager.
/// </summary> /// </summary>
public unsafe void AfterBuildFonts() /// <param name="forceMinSize">Whether to load fonts in minimum sizes.</param>
public unsafe void AfterBuildFonts(bool forceMinSize)
{ {
var ioFonts = ImGui.GetIO().Fonts; var ioFonts = ImGui.GetIO().Fonts;
ioFonts.GetTexDataAsRGBA32(out byte* pixels8, out var width, out var height); ioFonts.GetTexDataAsRGBA32(out byte* pixels8, out var width, out var height);
@ -347,7 +353,8 @@ namespace Dalamud.Interface.GameFonts
foreach (var (style, font) in this.fonts) foreach (var (style, font) in this.fonts)
{ {
var fdt = this.fdts[(int)style.FamilyAndSize]; var fdt = this.fdts[(int)(forceMinSize ? style.FamilyWithMinimumSize : style.FamilyAndSize)];
var scale = style.SizePt / fdt.FontHeader.Size;
var fontPtr = font.NativePtr; var fontPtr = font.NativePtr;
fontPtr->ConfigData->SizePixels = fontPtr->FontSize = fdt.FontHeader.Size * 4 / 3; fontPtr->ConfigData->SizePixels = fontPtr->FontSize = fdt.FontHeader.Size * 4 / 3;
fontPtr->Ascent = fdt.FontHeader.Ascent; fontPtr->Ascent = fdt.FontHeader.Ascent;
@ -363,19 +370,15 @@ namespace Dalamud.Interface.GameFonts
} }
} }
fixed (char* c = FontNames[(int)style.FamilyAndSize]) var nameBytes = Encoding.UTF8.GetBytes(style.ToString() + "\0");
{ Marshal.Copy(nameBytes, 0, (IntPtr)font.ConfigData.Name.Data, Math.Min(nameBytes.Length, font.ConfigData.Name.Count));
for (var j = 0; j < 40; j++)
fontPtr->ConfigData->Name[j] = 0;
Encoding.UTF8.GetBytes(c, FontNames[(int)style.FamilyAndSize].Length, fontPtr->ConfigData->Name, 40);
}
foreach (var (c, (rectId, glyph)) in this.glyphRectIds[style]) foreach (var (c, (rectId, glyph)) in this.glyphRectIds[style])
{ {
var rc = ioFonts.GetCustomRectByIndex(rectId); var rc = ioFonts.GetCustomRectByIndex(rectId);
var sourceBuffer = this.texturePixels[glyph.TextureFileIndex]; var sourceBuffer = this.texturePixels[glyph.TextureFileIndex];
var sourceBufferDelta = glyph.TextureChannelByteIndex; var sourceBufferDelta = glyph.TextureChannelByteIndex;
var widthAdjustment = style.CalculateWidthAdjustment(fdt, glyph); var widthAdjustment = style.CalculateBaseWidthAdjustment(fdt, glyph);
if (widthAdjustment == 0) if (widthAdjustment == 0)
{ {
for (var y = 0; y < glyph.BoundingHeight; y++) for (var y = 0; y < glyph.BoundingHeight; y++)
@ -401,10 +404,10 @@ namespace Dalamud.Interface.GameFonts
for (var y = 0; y < glyph.BoundingHeight; y++) for (var y = 0; y < glyph.BoundingHeight; y++)
{ {
float xDelta = xbold; float xDelta = xbold;
if (style.SkewStrength > 0) if (style.BaseSkewStrength > 0)
xDelta += style.SkewStrength * (fdt.FontHeader.LineHeight - glyph.CurrentOffsetY - y) / fdt.FontHeader.LineHeight; xDelta += style.BaseSkewStrength * (fdt.FontHeader.LineHeight - glyph.CurrentOffsetY - y) / fdt.FontHeader.LineHeight;
else if (style.SkewStrength < 0) else if (style.BaseSkewStrength < 0)
xDelta -= style.SkewStrength * (glyph.CurrentOffsetY + y) / fdt.FontHeader.LineHeight; xDelta -= style.BaseSkewStrength * (glyph.CurrentOffsetY + y) / fdt.FontHeader.LineHeight;
var xDeltaInt = (int)Math.Floor(xDelta); var xDeltaInt = (int)Math.Floor(xDelta);
var xness = xDelta - xDeltaInt; var xness = xDelta - xDeltaInt;
for (var x = 0; x < glyph.BoundingWidth; x++) for (var x = 0; x < glyph.BoundingWidth; x++)
@ -433,11 +436,9 @@ namespace Dalamud.Interface.GameFonts
} }
} }
} }
}
foreach (var font in this.fonts.Values)
{
CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, font, true, false); CopyGlyphsAcrossFonts(InterfaceManager.DefaultFont, font, true, false);
UnscaleFont(font, 1 / scale, false);
font.BuildLookupTable(); font.BuildLookupTable();
} }
} }

View file

@ -16,6 +16,11 @@ namespace Dalamud.Interface.GameFonts
/// </summary> /// </summary>
public GameFontFamilyAndSize FamilyAndSize; public GameFontFamilyAndSize FamilyAndSize;
/// <summary>
/// Size of the font in pixels unit.
/// </summary>
public float SizePx;
/// <summary> /// <summary>
/// Weight of the font. /// Weight of the font.
/// ///
@ -37,11 +42,12 @@ namespace Dalamud.Interface.GameFonts
/// Initializes a new instance of the <see cref="GameFontStyle"/> struct. /// Initializes a new instance of the <see cref="GameFontStyle"/> struct.
/// </summary> /// </summary>
/// <param name="family">Font family.</param> /// <param name="family">Font family.</param>
/// <param name="size">Size in points.</param> /// <param name="sizePx">Size in pixels.</param>
public GameFontStyle(GameFontFamily family, float size) public GameFontStyle(GameFontFamily family, float sizePx)
{ {
this.FamilyAndSize = GetRecommendedFamilyAndSize(family, size); this.FamilyAndSize = GetRecommendedFamilyAndSize(family, sizePx * 3 / 4);
this.Weight = this.SkewStrength = 0f; this.Weight = this.SkewStrength = 0f;
this.SizePx = sizePx;
} }
/// <summary> /// <summary>
@ -52,6 +58,29 @@ namespace Dalamud.Interface.GameFonts
{ {
this.FamilyAndSize = familyAndSize; this.FamilyAndSize = familyAndSize;
this.Weight = this.SkewStrength = 0f; this.Weight = this.SkewStrength = 0f;
// Dummy assignment to satisfy requirements
this.SizePx = 0;
this.SizePx = this.BaseSizePx;
}
/// <summary>
/// Gets or sets the size of the font in points unit.
/// </summary>
public float SizePt
{
get => this.SizePx * 3 / 4;
set => this.SizePx = value * 4 / 3;
}
/// <summary>
/// Gets or sets the base skew strength.
/// </summary>
public float BaseSkewStrength
{
get => this.SkewStrength * this.BaseSizePx / this.SizePx;
set => this.SkewStrength = value * this.SizePx / this.BaseSizePx;
} }
/// <summary> /// <summary>
@ -87,9 +116,23 @@ namespace Dalamud.Interface.GameFonts
}; };
/// <summary> /// <summary>
/// Gets the font size in point unit. /// Gets the corresponding GameFontFamilyAndSize but with minimum possible font sizes.
/// </summary> /// </summary>
public float SizePt => this.FamilyAndSize switch public GameFontFamilyAndSize FamilyWithMinimumSize => this.Family switch
{
GameFontFamily.Axis => GameFontFamilyAndSize.Axis96,
GameFontFamily.Jupiter => GameFontFamilyAndSize.Jupiter16,
GameFontFamily.JupiterNumeric => GameFontFamilyAndSize.Jupiter45,
GameFontFamily.Meidinger => GameFontFamilyAndSize.Meidinger16,
GameFontFamily.MiedingerMid => GameFontFamilyAndSize.MiedingerMid10,
GameFontFamily.TrumpGothic => GameFontFamilyAndSize.TrumpGothic184,
_ => GameFontFamilyAndSize.Undefined,
};
/// <summary>
/// Gets the base font size in point unit.
/// </summary>
public float BaseSizePt => this.FamilyAndSize switch
{ {
GameFontFamilyAndSize.Undefined => 0, GameFontFamilyAndSize.Undefined => 0,
GameFontFamilyAndSize.Axis96 => 9.6f, GameFontFamilyAndSize.Axis96 => 9.6f,
@ -119,9 +162,9 @@ namespace Dalamud.Interface.GameFonts
}; };
/// <summary> /// <summary>
/// Gets the font size in pixel unit. /// Gets the base font size in pixel unit.
/// </summary> /// </summary>
public float SizePx => this.SizePt * 4 / 3; public float BaseSizePx => this.BaseSizePt * 4 / 3;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether this font is bold. /// Gets or sets a value indicating whether this font is bold.
@ -138,7 +181,7 @@ namespace Dalamud.Interface.GameFonts
public bool Italic public bool Italic
{ {
get => this.SkewStrength != 0; get => this.SkewStrength != 0;
set => this.SkewStrength = value ? 4 : 0; set => this.SkewStrength = value ? this.SizePx / 7 : 0;
} }
/// <summary> /// <summary>
@ -226,15 +269,21 @@ namespace Dalamud.Interface.GameFonts
/// <param name="reader">Font information.</param> /// <param name="reader">Font information.</param>
/// <param name="glyph">Glyph.</param> /// <param name="glyph">Glyph.</param>
/// <returns>Width adjustment in pixel unit.</returns> /// <returns>Width adjustment in pixel unit.</returns>
public int CalculateWidthAdjustment(FdtReader reader, FdtReader.FontTableEntry glyph) public int CalculateBaseWidthAdjustment(FdtReader reader, FdtReader.FontTableEntry glyph)
{ {
var widthDelta = this.Weight; var widthDelta = this.Weight;
if (this.SkewStrength > 0) if (this.BaseSkewStrength > 0)
widthDelta += 1f * this.SkewStrength * (reader.FontHeader.LineHeight - glyph.CurrentOffsetY) / reader.FontHeader.LineHeight; widthDelta += 1f * this.BaseSkewStrength * (reader.FontHeader.LineHeight - glyph.CurrentOffsetY) / reader.FontHeader.LineHeight;
else if (this.SkewStrength < 0) else if (this.BaseSkewStrength < 0)
widthDelta -= 1f * this.SkewStrength * (glyph.CurrentOffsetY + glyph.BoundingHeight) / reader.FontHeader.LineHeight; widthDelta -= 1f * this.BaseSkewStrength * (glyph.CurrentOffsetY + glyph.BoundingHeight) / reader.FontHeader.LineHeight;
return (int)Math.Ceiling(widthDelta); return (int)Math.Ceiling(widthDelta);
} }
/// <inheritdoc/>
public override string ToString()
{
return $"GameFontStyle({this.FamilyAndSize}, {this.SizePt}pt, skew={this.SkewStrength}, weight={this.Weight})";
}
} }
} }

View file

@ -625,7 +625,7 @@ namespace Dalamud.Interface.Internal
this.Axis = axis; this.Axis = axis;
this.TargetSizePx = sizePx; this.TargetSizePx = sizePx;
this.Scale = scale; this.Scale = scale;
this.SourceAxis = Service<GameFontManager>.Get().NewFontRef(new(GameFontFamily.Axis, sizePx * scale * 3 / 4)); this.SourceAxis = Service<GameFontManager>.Get().NewFontRef(new(GameFontFamily.Axis, sizePx * scale));
} }
internal enum AxisMode internal enum AxisMode
@ -705,7 +705,7 @@ namespace Dalamud.Interface.Internal
this.UseAxis ? TargetFontModification.AxisMode.Overwrite : TargetFontModification.AxisMode.GameGlyphsOnly, this.UseAxis ? TargetFontModification.AxisMode.Overwrite : TargetFontModification.AxisMode.GameGlyphsOnly,
this.UseAxis ? DefaultFontSizePx : DefaultFontSizePx + 1, this.UseAxis ? DefaultFontSizePx : DefaultFontSizePx + 1,
fontLoadScale); fontLoadScale);
Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis.Style.SizePt, fontInfo.SourceAxis.Style.SizePx); Log.Verbose("[FONT] SetupFonts - Default corresponding AXIS size: {0}pt ({1}px)", fontInfo.SourceAxis.Style.BaseSizePt, fontInfo.SourceAxis.Style.BaseSizePx);
if (this.UseAxis) if (this.UseAxis)
{ {
fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject(); fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject();
@ -807,7 +807,7 @@ namespace Dalamud.Interface.Internal
if (this.UseAxis) if (this.UseAxis)
{ {
fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject(); fontConfig.GlyphRanges = dummyRangeHandle.AddrOfPinnedObject();
fontConfig.SizePixels = fontInfo.SourceAxis.Style.SizePx; fontConfig.SizePixels = fontInfo.SourceAxis.Style.BaseSizePx;
fontConfig.PixelSnapH = false; fontConfig.PixelSnapH = false;
var sizedFont = ioFonts.AddFontDefault(fontConfig); var sizedFont = ioFonts.AddFontDefault(fontConfig);
@ -829,7 +829,7 @@ namespace Dalamud.Interface.Internal
} }
} }
gameFontManager.BuildFonts(); gameFontManager.BuildFonts(disableBigFonts);
var customFontFirstConfigIndex = ioFonts.ConfigData.Size; var customFontFirstConfigIndex = ioFonts.ConfigData.Size;
@ -903,7 +903,7 @@ namespace Dalamud.Interface.Internal
texPixels[i] = (byte)(Math.Pow(texPixels[i] / 255.0f, 1.0f / fontGamma) * 255.0f); texPixels[i] = (byte)(Math.Pow(texPixels[i] / 255.0f, 1.0f / fontGamma) * 255.0f);
} }
gameFontManager.AfterBuildFonts(); gameFontManager.AfterBuildFonts(disableBigFonts);
foreach (var (font, mod) in this.loadedFontInfo) foreach (var (font, mod) in this.loadedFontInfo)
{ {