Files
2026-07-13 13:13:17 +08:00

127 lines
5.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#nullable enable
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using ImGuiNET;
using SilkWindows;
using T3.Core.Resource;
using T3.Editor.App;
using T3.Editor.Gui;
using T3.Editor.Gui.Styling;
using T3.Editor.Gui.UiHelpers;
namespace T3.Editor.UiContentDrawing;
internal static class UiContentUpdate
{
public static void SetupResourcesAndFontsWithScaling()
{
if (_hasSetScaling && Math.Abs(UserSettings.Config.UiScaleFactor - _lastUiScale) <= 0.005f)
return;
Log.Debug("Setup editor resources...");
// Prevent scale factor from being "actually" 0.0
if (UserSettings.Config.UiScaleFactor < 0.1f)
UserSettings.Config.UiScaleFactor = 0.1f;
// Update font atlas texture if UI-Scale changed
GenerateFontsWithScaleFactor(UserSettings.Config.UiScaleFactor);
Program.UiContentContentDrawer?.CreateDeviceObjectsAndFonts();
_lastUiScale = UserSettings.Config.UiScaleFactor;
_hasSetScaling = true;
}
private static void GenerateFontsWithScaleFactor(float scaleFactor)
{
// See https://stackoverflow.com/a/5977638
var displayScaleFactor = ProgramWindows.Main.GetDpi().X / 96f;
var dpiAwareScale = scaleFactor * displayScaleFactor;
T3Ui.UiScaleFactor = dpiAwareScale;
var fontAtlasPtr = ImGui.GetIO().Fonts;
fontAtlasPtr.Clear();
const string fontName = "Inter";
var rootFilePath = Path.Combine(SharedResources.EditorResourcesDirectory, SharedResources.EditorResourcesDirectory, "fonts", fontName + '-');
const string fileExtension = ".ttf";
var format = $"{rootFilePath}{{0}}{fileExtension}";
var normalFont = new TtfFont(string.Format(format, "Regular"), 18f * dpiAwareScale);
var boldFont = new TtfFont(string.Format(format, "SemiBold"), 18f * dpiAwareScale);
var smallFont = new TtfFont(string.Format(format, "Regular"), 14f * dpiAwareScale);
var largeFont = new TtfFont(string.Format(format, "Light"), 30f * dpiAwareScale);
var ranges = GetExtendedGlyphRanges();
Fonts.FontNormal = fontAtlasPtr.AddFontFromFileTTF(normalFont.Path, normalFont.PixelSize, default, ranges);
Fonts.FontBold = fontAtlasPtr.AddFontFromFileTTF(boldFont.Path, boldFont.PixelSize, default, ranges);
Fonts.FontSmall = fontAtlasPtr.AddFontFromFileTTF(smallFont.Path, smallFont.PixelSize, default, ranges);
Fonts.FontLarge = fontAtlasPtr.AddFontFromFileTTF(largeFont.Path, largeFont.PixelSize, default, ranges);
var codeFontPath = Path.Combine(SharedResources.EditorResourcesDirectory, SharedResources.EditorResourcesDirectory,"fonts", "JetBrainsMono-Regular.ttf");
var codeFont = new TtfFont(codeFontPath, 18f * dpiAwareScale);
Fonts.Code = fontAtlasPtr.AddFontFromFileTTF(codeFont.Path, codeFont.PixelSize, default, ranges);
ImGuiWindowService.Instance.SetFonts(new FontPack(normalFont, boldFont, smallFont, largeFont));
}
/// <summary>
/// Extended glyph ranges for the editor's TTF fonts. Default ImGui only
/// rasterizes 0x0020-0x00FF (basic Latin); we additionally pull in common
/// punctuation used by the markdown renderer (bullet •, dashes —, smart
/// quotes ' ' " ", ellipsis …), arrows (→ ← ↑ ↓), miscellaneous symbols
/// (warning ⚠, gear ⚙), and dingbats (check ✓, cross ✗).
///
/// The returned pointer references a static, GC-pinned array — ImGui only
/// reads from it during atlas Build(), so the pin can live for the
/// process lifetime.
/// </summary>
private static IntPtr GetExtendedGlyphRanges()
{
if (_glyphRangesPtr != IntPtr.Zero)
return _glyphRangesPtr;
// Pairs of (first, last), terminated with 0.
_extendedGlyphRanges = new ushort[]
{
0x0020, 0x00FF, // Basic Latin + Latin Supplement
0x2010, 0x205E, // General punctuation
0x2190, // ←
0x21FF, // ⇿
0x2192, // → Right arrow
0x2600, 0x26FF, // Miscellaneous symbols (⚠ ⚙ ☆ …)
0x2700, 0x27BF, // Dingbats (✓ ✗ ✱ …)
0,
};
_glyphRangesHandle = GCHandle.Alloc(_extendedGlyphRanges, GCHandleType.Pinned);
_glyphRangesPtr = _glyphRangesHandle.AddrOfPinnedObject();
return _glyphRangesPtr;
}
private static ushort[]? _extendedGlyphRanges;
private static GCHandle _glyphRangesHandle;
private static IntPtr _glyphRangesPtr;
private static long _lastElapsedTicks;
private static readonly Stopwatch _stopwatch = new();
private static float _lastUiScale = 1;
private static bool _hasSetScaling;
public static void StartMeasureFrame()
{
_stopwatch.Start();
_lastElapsedTicks = _stopwatch.ElapsedTicks;
}
public static void TakeMeasurement()
{
Int64 ticks = _stopwatch.ElapsedTicks;
Int64 ticksDiff = ticks - _lastElapsedTicks;
_lastElapsedTicks = ticks;
ImGui.GetIO().DeltaTime = (float)((double)(ticksDiff) / Stopwatch.Frequency);
}
}