feat(style): put mixed sizes on a shared baseline
ImGui lines items up by their top edge. ItemSize only shifts anything when CurrLineTextBaseOffset is non-zero, and that stays zero unless AlignTextToFramePadding ran -- so a meta timestamp beside a body-sized name would sit flush at the top and float above the baseline. The correction is the difference of the two ascents, scaled. The scaling looks like it is applied twice and is not: Dalamud rasterises at SizePx * GlobalScale and then divides the metrics back down, so ImFont.Ascent comes out logical. Drawing multiplies it up again. The comment says so, because the first reviewer to see this file read it the other way. No call site yet -- the self-test in the next commit takes it, and the message list takes it in block C.
This commit is contained in:
@@ -0,0 +1,19 @@
|
|||||||
|
namespace HellionChat.Ui.StyleEngine;
|
||||||
|
|
||||||
|
// TEST-MIRROR: Ui/BaselineMathTests.cs
|
||||||
|
//
|
||||||
|
// ImGui lines items up on a row by their top edge, not their baseline: ItemSize
|
||||||
|
// only shifts anything when CurrLineTextBaseOffset is non-zero, and that stays at
|
||||||
|
// zero unless AlignTextToFramePadding ran. So a smaller face beside a larger one
|
||||||
|
// hangs, flush at the top and floating above the baseline.
|
||||||
|
//
|
||||||
|
// The correction is the difference between the two ascents. It is easy to assume
|
||||||
|
// the display scale is applied twice here and it is not: Dalamud rasterises at
|
||||||
|
// SizePx * GlobalScale and then divides the metrics straight back down
|
||||||
|
// (ImGuiHelpers.AdjustGlyphMetrics(1 / scale, ...)), so ImFont.Ascent is a
|
||||||
|
// logical value. Drawing multiplies it up again -- and so must this.
|
||||||
|
internal static class BaselineMath
|
||||||
|
{
|
||||||
|
internal static float OffsetFor(float ascentLarge, float ascentSmall, float uiScale) =>
|
||||||
|
MathF.Max(0f, (ascentLarge - ascentSmall) * uiScale);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user