A comment that reads "MUST stay in lockstep with TryGetActiveCrossfade (K8)" helps nobody outside the plan that used to have a K8 in it, and the plans are not in this repo. Same for "Spec FR-4", "plan §B.2", "Sub-Task 4.4" and the F/R/M/A/S round codes scattered through the style engine and the self-tests. Personal names go too. "tester feedback from Jin (v1.4.7)" and "Flo decision 2026-06-15" carry the reason fine without naming anyone -- the version and the reason are the parts a reader can act on, and a public repo should not need a cast list to be read. The rule applied throughout: keep the why, drop the reference. Version numbers stay, since those resolve through the changelog. 77 files. ChunkUtil also carried 281 lines of commented-out code -- an older ToChunks variant and two helpers with no callers, inherited and never removed. Deleted; git remembers them.
165 lines
5.5 KiB
C#
165 lines
5.5 KiB
C#
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Plugin.SelfTest;
|
|
|
|
namespace HellionChat.SelfTests;
|
|
|
|
// Verifies the FontManager came out of the DI container with every
|
|
// handle attached and no atlas-load failure on any of them. ItalicFont
|
|
// is allowed to be null when ItalicEnabled is off.
|
|
internal sealed class FontManagerCtorSmokeStep : ISelfTestStep
|
|
{
|
|
private readonly Plugin plugin;
|
|
|
|
public FontManagerCtorSmokeStep(Plugin plugin)
|
|
{
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
public string Name => "Hellion Chat - FontManager ctor smoke";
|
|
|
|
public SelfTestStepResult RunStep()
|
|
{
|
|
var fm = this.plugin.FontManager;
|
|
if (fm is null)
|
|
{
|
|
ImGui.Text("Plugin.FontManager is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.Axis is null)
|
|
{
|
|
ImGui.Text("Axis handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.AxisItalic is null)
|
|
{
|
|
ImGui.Text("AxisItalic handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.FontAwesome is null)
|
|
{
|
|
ImGui.Text("FontAwesome handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.RegularFont is null)
|
|
{
|
|
ImGui.Text("RegularFont handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (Plugin.Config.ItalicEnabled && fm.ItalicFont is null)
|
|
{
|
|
ImGui.Text("ItalicEnabled is on but ItalicFont handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
// v1.13.0: unconditional, unlike ItalicFont. Both are always built, and a
|
|
// handle that never arrives makes SimplePushedFont push nothing silently.
|
|
if (fm.SenderFont is null)
|
|
{
|
|
ImGui.Text("SenderFont handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.MetaFont is null)
|
|
{
|
|
ImGui.Text("MetaFont handle is null");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.Axis.LoadException is { } e1)
|
|
{
|
|
ImGui.Text($"Axis load exception: {e1.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.AxisItalic.LoadException is { } e2)
|
|
{
|
|
ImGui.Text($"AxisItalic load exception: {e2.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.FontAwesome.LoadException is { } e3)
|
|
{
|
|
ImGui.Text($"FontAwesome load exception: {e3.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.RegularFont.LoadException is { } e4)
|
|
{
|
|
ImGui.Text($"RegularFont load exception: {e4.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.ItalicFont?.LoadException is { } e5)
|
|
{
|
|
ImGui.Text($"ItalicFont load exception: {e5.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.SenderFont.LoadException is { } e6)
|
|
{
|
|
ImGui.Text($"SenderFont load exception: {e6.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
if (fm.MetaFont.LoadException is { } e7)
|
|
{
|
|
ImGui.Text($"MetaFont load exception: {e7.Message}");
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
// B1: assert the atlas actually finished building all required handles,
|
|
// not just that the references are non-null. FontsReady is the observable
|
|
// state the trimmed-fallback rebuild must still reach; a half-built atlas
|
|
// would pass the null/exception checks above but fail here.
|
|
if (!fm.FontsReady)
|
|
{
|
|
ImGui.Text("FontManager.FontsReady is false (atlas not fully built).");
|
|
SelfTestReport.Append(
|
|
Name,
|
|
"FAIL",
|
|
new[] { "FontsReady is false — atlas not fully built." }
|
|
);
|
|
return SelfTestStepResult.Fail;
|
|
}
|
|
|
|
// Report what was actually verified rather than a bare Pass.
|
|
// The glyph-range entry counts make the B1 dedup visible — the cjk-fallback
|
|
// range is now a small trimmed remainder next to the large primary range.
|
|
var counts = fm.GlyphRangeLengths;
|
|
var italicState =
|
|
fm.ItalicFont is null ? "disabled (null)"
|
|
: fm.ItalicFont.Available ? "available"
|
|
: "NOT available";
|
|
var path = SelfTestReport.Append(
|
|
Name,
|
|
"PASS",
|
|
new[]
|
|
{
|
|
$"Axis available: {fm.Axis.Available}",
|
|
$"AxisItalic available: {fm.AxisItalic.Available}",
|
|
$"FontAwesome available: {fm.FontAwesome.Available}",
|
|
$"RegularFont available: {fm.RegularFont.Available}",
|
|
$"ItalicFont: {italicState}",
|
|
$"SenderFont available: {fm.SenderFont.Available} (weight {FontManager.SenderWeight:0.00})",
|
|
$"MetaFont available: {fm.MetaFont.Available}",
|
|
$"FontsReady: {fm.FontsReady}",
|
|
$"Glyph-range entries: primary={counts.Ranges}, jp={counts.JpRange}, "
|
|
+ $"cjk-fallback={counts.CjkFallback} (B1 trimmed)",
|
|
$"UseHellionFont={Plugin.Config.UseHellionFont}, ItalicEnabled={Plugin.Config.ItalicEnabled}",
|
|
}
|
|
);
|
|
ImGui.Text(
|
|
$"PASS — FontsReady, ranges primary={counts.Ranges}/jp={counts.JpRange}/"
|
|
+ $"cjk-fallback={counts.CjkFallback}. Report: {path}"
|
|
);
|
|
return SelfTestStepResult.Pass;
|
|
}
|
|
|
|
public void CleanUp() { }
|
|
}
|