|
| 1 | +// Copyright (c) 2023-2026 ktsu-dev contributors |
| 2 | + |
| 3 | +namespace ktsu.Schema.Editor; |
| 4 | + |
| 5 | +using Hexa.NET.ImGui; |
| 6 | + |
| 7 | +/// <summary> |
| 8 | +/// Spells a unit's text in characters the editor's font can draw. |
| 9 | +/// </summary> |
| 10 | +/// <remarks> |
| 11 | +/// <para> |
| 12 | +/// Unit symbols come from ktsu.Semantics.Quantities and write a negative exponent with the |
| 13 | +/// superscript minus, U+207B: <c>s⁻¹</c>, <c>m·s⁻²</c>. The font ImGuiApp ships, JetBrains Mono |
| 14 | +/// Nerd Font, has every superscript digit and the superscript plus but not that one character, so |
| 15 | +/// it drew as the fallback glyph and a frequency read <c>s?¹</c>. Widening the glyph ranges cannot |
| 16 | +/// help, because the glyph is missing from the font rather than from the ranges. |
| 17 | +/// </para> |
| 18 | +/// <para> |
| 19 | +/// Where the font has no glyph for it, the minus is drawn as a macron, U+00AF, which sits at the |
| 20 | +/// height of the superscript digits beside it and is the usual stand-in for a raised minus. This is |
| 21 | +/// display only: what is written to the schema file is untouched, and as soon as the font gains the |
| 22 | +/// real glyph it is drawn instead. |
| 23 | +/// </para> |
| 24 | +/// </remarks> |
| 25 | +internal static class UnitText |
| 26 | +{ |
| 27 | + /// <summary>The superscript minus unit symbols use for negative exponents.</summary> |
| 28 | + internal const char SuperscriptMinus = '⁻'; |
| 29 | + |
| 30 | + /// <summary>The raised bar drawn in its place when the font has no superscript minus.</summary> |
| 31 | + internal const char RaisedBar = '¯'; |
| 32 | + |
| 33 | + /// <summary> |
| 34 | + /// Returns <paramref name="text"/> as it should be drawn in the current font. |
| 35 | + /// </summary> |
| 36 | + /// <remarks>Call during a frame: whether the font has the glyph is asked of the font in use.</remarks> |
| 37 | + /// <param name="text">A unit's symbol, or text containing one.</param> |
| 38 | + /// <returns>The text, with the superscript minus replaced when the font cannot draw it.</returns> |
| 39 | + internal static string ForDisplay(string text) => |
| 40 | + text.Contains(SuperscriptMinus) && !FontHasSuperscriptMinus() |
| 41 | + ? text.Replace(SuperscriptMinus, RaisedBar) |
| 42 | + : text; |
| 43 | + |
| 44 | + private static bool FontHasSuperscriptMinus() |
| 45 | + { |
| 46 | + ImFontPtr font = ImGui.GetFont(); |
| 47 | + return !font.IsNull && font.IsGlyphInFont(SuperscriptMinus); |
| 48 | + } |
| 49 | +} |
0 commit comments