Files
RobustToolbox/Robust.Client/Graphics/FontManagement/SystemFontDebugWindow.xaml.cs
T
Pieter-Jan BriersandGitHub f3a3f564e1 System font API (#5393)
* System font API

This is a new API that allows operating system fonts to be loaded by the engine and used by content.

Fonts are provided in a flat list exposing all the relevant metadata. They are loaded from disk with a Load call.

Initial implementation is only for Windows DirectWrite.

* Load system fonts as memory mapped files if possible.

This allows sharing the font file memory with other processes which is always good.

* Use ArrayPool to reduce char array allocations

* Disable verbose logging

* Implement system font support on Linux via Fontconfig

* Implement macOS support

* Add "FREEDESKTOP" define constant

This is basically LINUX || FREEBSD. Though FreeBSD currently gets detected as LINUX too. Oh well.

* Compile out Fontconfig and CoreText system font backends when not on those platforms

* Don't add Fontconfig package dep on Mac/Windows

* Allow disabling system font support via CVar

Cuz why not.
2025-10-28 22:07:55 +01:00

99 lines
3.2 KiB
C#

using System.Linq;
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Client.UserInterface.XAML;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Utility;
namespace Robust.Client.Graphics.FontManagement;
[GenerateTypedNameReferences]
internal sealed partial class SystemFontDebugWindow : DefaultWindow
{
private static readonly int[] ExampleFontSizes = [8, 12, 16, 24, 36];
private const string ExampleString = "The quick brown fox jumps over the lazy dog";
[Dependency] private readonly ISystemFontManager _systemFontManager = default!;
public SystemFontDebugWindow()
{
IoCManager.InjectDependencies(this);
RobustXamlLoader.Load(this);
var buttonGroup = new ButtonGroup();
foreach (var group in _systemFontManager.SystemFontFaces.GroupBy(k => k.FamilyName).OrderBy(k => k.Key))
{
var fonts = group.ToArray();
SelectorContainer.AddChild(new Selector(this, buttonGroup, group.Key, fonts));
}
}
private void SelectFontFamily(ISystemFontFace[] fonts)
{
FamilyLabel.Text = fonts[0].FamilyName;
FaceContainer.RemoveAllChildren();
foreach (var font in fonts)
{
var exampleContainer = new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
Margin = new Thickness(8)
};
foreach (var size in ExampleFontSizes)
{
var fontInstance = font.Load(size);
var richTextLabel = new RichTextLabel
{
Stylesheet = new Stylesheet([
StylesheetHelpers.Element<RichTextLabel>().Prop("font", fontInstance)
]),
};
richTextLabel.SetMessage(FormattedMessage.FromUnformatted(ExampleString));
exampleContainer.AddChild(richTextLabel);
}
FaceContainer.AddChild(new BoxContainer
{
Orientation = BoxContainer.LayoutOrientation.Vertical,
Children =
{
new RichTextLabel
{
Text = $"""
{font.FullName}
Family: "{font.FamilyName}", face: "{font.FaceName}", PostScript = "{font.PostscriptName}"
Weight: {font.Weight} ({(int) font.Weight}), slant: {font.Slant} ({(int) font.Slant}), width: {font.Width} ({(int) font.Width})
""",
},
exampleContainer
},
Margin = new Thickness(0, 0, 0, 8)
});
}
}
private sealed class Selector : Control
{
public Selector(SystemFontDebugWindow window, ButtonGroup group, string family, ISystemFontFace[] fonts)
{
var button = new Button
{
Text = family,
Group = group,
ToggleMode = true
};
AddChild(button);
button.OnPressed += _ => window.SelectFontFamily(fonts);
}
}
}