b451f83174
Captures the pre-Godot-port state of the codebase. This is the rollback anchor for the Godot port (M0 of theriapolis-rpg-implementation-plan-godot-port.md). All Phase 0 through Phase 6.5 work is included; Phase 7 is in flight. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
83 lines
4.0 KiB
C#
83 lines
4.0 KiB
C#
using FontStashSharp;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
namespace Theriapolis.Game.CodexUI.Core;
|
|
|
|
/// <summary>
|
|
/// Static font registry for CodexUI. Loaded once at game startup via
|
|
/// <see cref="LoadAll"/>; widgets read from these fields. The slots map to
|
|
/// the design's typographic ladder:
|
|
/// - DisplayLarge / Medium / Small → Cinzel-Bold (fallback: Georgia Bold) — all-caps headings
|
|
/// - SerifBody / SerifItalic → Cormorant Garamond (fallback: Georgia / Georgia Italic)
|
|
/// - MonoTag / MonoTagSmall → JetBrains Mono (fallback: Consolas)
|
|
///
|
|
/// FontStashSharp loads TTF files into a runtime atlas. We try
|
|
/// <c>Content/Fonts/</c> first (project-supplied fonts), then fall back to
|
|
/// Windows system fonts so the game runs without bundling Cinzel/Cormorant.
|
|
/// </summary>
|
|
public static class CodexFonts
|
|
{
|
|
public static SpriteFontBase DisplayLarge = null!; // ~32 px, codex header
|
|
public static SpriteFontBase DisplayMedium = null!; // ~22 px, h2
|
|
public static SpriteFontBase DisplaySmall = null!; // ~16 px, h3
|
|
public static SpriteFontBase SerifBody = null!; // ~16 px, body text
|
|
public static SpriteFontBase SerifItalic = null!; // ~14 px, italic body / trait names
|
|
public static SpriteFontBase MonoTag = null!; // ~10 px, eyebrow + tag text
|
|
public static SpriteFontBase MonoTagSmall = null!; // ~9 px, sub-tags
|
|
|
|
private static FontSystem? _serif;
|
|
private static FontSystem? _italic;
|
|
private static FontSystem? _mono;
|
|
|
|
/// <summary>
|
|
/// Load every font slot. Throws on failure — fonts are required for the
|
|
/// codex screen to render anything legible.
|
|
/// </summary>
|
|
public static void LoadAll(GraphicsDevice gd, string contentRoot)
|
|
{
|
|
_serif = LoadFontSystem(contentRoot, new[] { "Fonts/Cinzel-Bold.ttf", "Fonts/CormorantGaramond-Bold.ttf" },
|
|
new[] { @"C:\Windows\Fonts\georgiab.ttf", @"C:\Windows\Fonts\timesbd.ttf" });
|
|
_italic = LoadFontSystem(contentRoot, new[] { "Fonts/CormorantGaramond-Italic.ttf", "Fonts/CormorantGaramond-Regular.ttf" },
|
|
new[] { @"C:\Windows\Fonts\georgiai.ttf", @"C:\Windows\Fonts\timesi.ttf", @"C:\Windows\Fonts\georgia.ttf" });
|
|
_mono = LoadFontSystem(contentRoot, new[] { "Fonts/JetBrainsMono-Medium.ttf" },
|
|
new[] { @"C:\Windows\Fonts\consola.ttf", @"C:\Windows\Fonts\consolab.ttf", @"C:\Windows\Fonts\cour.ttf" });
|
|
|
|
DisplayLarge = _serif.GetFont(32f);
|
|
DisplayMedium = _serif.GetFont(22f);
|
|
DisplaySmall = _serif.GetFont(16f);
|
|
SerifBody = _italic.GetFont(15f);
|
|
SerifItalic = _italic.GetFont(14f);
|
|
MonoTag = _mono.GetFont(11f);
|
|
MonoTagSmall = _mono.GetFont(9f);
|
|
}
|
|
|
|
private static FontSystem LoadFontSystem(string contentRoot, string[] preferred, string[] fallbacks)
|
|
{
|
|
var fs = new FontSystem();
|
|
// Try project-supplied fonts first (Content/Fonts/*).
|
|
foreach (var rel in preferred)
|
|
{
|
|
string path = System.IO.Path.Combine(contentRoot, rel);
|
|
if (System.IO.File.Exists(path))
|
|
{
|
|
fs.AddFont(System.IO.File.ReadAllBytes(path));
|
|
return fs;
|
|
}
|
|
}
|
|
// Fall back to a system font — guaranteed available on the target
|
|
// platforms (Windows Georgia/Times/Consolas; future: macOS / Linux
|
|
// would need their own fallback list).
|
|
foreach (var path in fallbacks)
|
|
{
|
|
if (System.IO.File.Exists(path))
|
|
{
|
|
fs.AddFont(System.IO.File.ReadAllBytes(path));
|
|
return fs;
|
|
}
|
|
}
|
|
throw new System.IO.FileNotFoundException(
|
|
"CodexFonts: no font found in either project Content/Fonts/ or system fallback locations. " +
|
|
$"Preferred: {string.Join(", ", preferred)}; fallbacks: {string.Join(", ", fallbacks)}");
|
|
}
|
|
}
|