ImGuiManager: Support multiple text fonts

pull/3744/head
Stenzek 2 months ago
parent 38bbc115c5
commit bbe65219a2
No known key found for this signature in database

@ -2312,6 +2312,16 @@ void FullscreenUI::DrawInterfaceSettingsPage()
"", FullscreenUI::GetThemeDisplayNames(), FullscreenUI::GetThemeNames(), true, false,
[](std::string_view) { BeginTransition(LONG_TRANSITION_TIME, &FullscreenUI::UpdateTheme); });
DrawStringListSetting(bsi, FSUI_ICONVSTR(ICON_FA_FONT, "Font"), FSUI_VSTR("Selects the font used for UI text."),
"Main", "ImGuiTextFont", ImGuiManager::GetDefaultTextFontName(),
ImGuiManager::GetTextFontDisplayNames(), ImGuiManager::GetTextFontNames(), true, false,
[](std::string_view) {
// defer it, since we can't change the fonts while rendering
BeginTransition(LONG_TRANSITION_TIME, []() {
Host::RunOnCoreThread([]() { VideoThread::RunOnThread(&ImGuiManager::UpdateTextFont); });
});
});
if (const TinyString current_value =
bsi->GetTinyStringValue("Main", "FullscreenUIBackground", DEFAULT_BACKGROUND_NAME);
MenuActionButton(FSUI_ICONVSTR(ICON_FA_IMAGE, "Menu Background"),
@ -2467,6 +2477,15 @@ void FullscreenUI::DrawInterfaceSettingsPage()
"OSDMessageLocation", Settings::DEFAULT_OSD_MESSAGE_LOCATION, &Settings::ParseNotificationLocation,
&Settings::GetNotificationLocationName, &Settings::GetNotificationLocationDisplayName,
NotificationLocation::MaxCount);
DrawStringListSetting(bsi, FSUI_ICONVSTR(ICON_FA_FONT, "Overlay Font"),
FSUI_VSTR("Selects the font used for the performance overlay."), "Main", "ImGuiFixedFont",
ImGuiManager::GetDefaultFixedFontName(), ImGuiManager::GetFixedFontDisplayNames(),
ImGuiManager::GetFixedFontNames(), true, true, [](std::string_view) {
// defer it, since we can't change the fonts while rendering
BeginTransition(LONG_TRANSITION_TIME, []() {
Host::RunOnCoreThread([]() { VideoThread::RunOnThread(&ImGuiManager::UpdateFixedFont); });
});
});
DrawToggleSetting(bsi, FSUI_ICONVSTR(ICON_FA_CIRCLE_EXCLAMATION, "Show Messages"),
FSUI_VSTR("Shows on-screen-display messages when events occur. Errors and warnings are still "

@ -384,6 +384,7 @@ TRANSLATE_NOOP("FullscreenUI", "File Size");
TRANSLATE_NOOP("FullscreenUI", "File Title");
TRANSLATE_NOOP("FullscreenUI", "Fine Crop Amount");
TRANSLATE_NOOP("FullscreenUI", "Fine Crop Mode");
TRANSLATE_NOOP("FullscreenUI", "Font");
TRANSLATE_NOOP("FullscreenUI", "Force 4:3 For FMVs");
TRANSLATE_NOOP("FullscreenUI", "Forces a full rescan of all games previously identified.");
TRANSLATE_NOOP("FullscreenUI", "Forces texture upload tracking to be enabled regardless of whether it is needed.");
@ -553,6 +554,7 @@ TRANSLATE_NOOP("FullscreenUI", "Options");
TRANSLATE_NOOP("FullscreenUI", "Output Latency");
TRANSLATE_NOOP("FullscreenUI", "Output Volume");
TRANSLATE_NOOP("FullscreenUI", "Overclocking Percentage");
TRANSLATE_NOOP("FullscreenUI", "Overlay Font");
TRANSLATE_NOOP("FullscreenUI", "Overlays or replaces normal triangle drawing with a wireframe/line view.");
TRANSLATE_NOOP("FullscreenUI", "PGXP (Precision Geometry Transform Pipeline)");
TRANSLATE_NOOP("FullscreenUI", "PGXP Depth Buffer");
@ -699,6 +701,8 @@ TRANSLATE_NOOP("FullscreenUI", "Selects between Xbox/PlayStation button icons in
TRANSLATE_NOOP("FullscreenUI", "Selects the GPU to use for rendering.");
TRANSLATE_NOOP("FullscreenUI", "Selects the backend to use for rendering the console/game visuals.");
TRANSLATE_NOOP("FullscreenUI", "Selects the color style to be used for Big Picture UI.");
TRANSLATE_NOOP("FullscreenUI", "Selects the font used for UI text.");
TRANSLATE_NOOP("FullscreenUI", "Selects the font used for the performance overlay.");
TRANSLATE_NOOP("FullscreenUI", "Selects the percentage of the normal clock speed the emulated hardware will run at.");
TRANSLATE_NOOP("FullscreenUI", "Selects the quality at which screenshots will be compressed.");
TRANSLATE_NOOP("FullscreenUI", "Selects the resolution scale that will be applied to the final image. 1x will downsample to the original console resolution.");

@ -1313,6 +1313,18 @@ void VideoThread::ReportFatalErrorAndShutdown(std::string_view reason)
DebugAssert(IsOnThread());
std::string message = fmt::format("GPU thread shut down with fatal error:\n\n{}", reason);
if (!s_state.gpu_backend)
{
// if we have no backend, it crapped out in fullscreenui alone
if (!g_gpu_device)
return;
Host::RunOnCoreThread([message = std::move(message)]() { Host::OnSystemAbnormalShutdown(message); });
DestroyDeviceOnThread(false);
return;
}
Host::RunOnCoreThread([message = std::move(message)]() { System::AbnormalShutdown(message); });
// replace the renderer with a dummy/null backend, so that all commands get dropped

@ -8,6 +8,9 @@
#include "core/fullscreenui_widgets.h"
#include "core/settings.h"
#include "core/video_thread.h"
#include "util/imgui_manager.h"
#include "common/error.h"
@ -25,6 +28,10 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* dialog, QWidget* parent) :
SettingWidgetBinder::BindWidgetToFloatSetting(sif, m_ui.osdMargin, "Display", "OSDMargin",
ImGuiManager::DEFAULT_SCREEN_MARGIN);
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.fullscreenUITheme, "UI", "FullscreenUITheme");
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.imguiFont, "Main", "ImGuiTextFont",
ImGuiManager::GetDefaultTextFontName());
SettingWidgetBinder::BindWidgetToStringSetting(sif, m_ui.imguiFixedFont, "Main", "ImGuiFixedFont",
ImGuiManager::GetDefaultFixedFontName());
SettingWidgetBinder::BindWidgetToEnumSetting(
sif, m_ui.osdMessageLocation, "Display", "OSDMessageLocation", &Settings::ParseNotificationLocation,
&Settings::GetNotificationLocationName, &Settings::GetNotificationLocationDisplayName,
@ -61,6 +68,16 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* dialog, QWidget* parent) :
connect(m_ui.fullscreenUITheme, &QComboBox::currentIndexChanged, g_core_thread, &CoreThread::updateFullscreenUITheme);
connect(m_ui.showMessages, &QCheckBox::checkStateChanged, this, &OSDSettingsWidget::onOSDShowMessagesChanged);
connect(m_ui.imguiFont, &QComboBox::currentIndexChanged, g_core_thread, []() {
// don't bother if nothing is running
if (VideoThread::IsFullscreenUIRequested() || VideoThread::IsGPUBackendRequested())
VideoThread::RunOnThread(&ImGuiManager::UpdateTextFont);
});
connect(m_ui.imguiFixedFont, &QComboBox::currentIndexChanged, g_core_thread, []() {
// don't bother if nothing is running
if (VideoThread::IsFullscreenUIRequested() || VideoThread::IsGPUBackendRequested())
VideoThread::RunOnThread(&ImGuiManager::UpdateFixedFont);
});
onOSDShowMessagesChanged();
@ -69,6 +86,15 @@ OSDSettingsWidget::OSDSettingsWidget(SettingsWindow* dialog, QWidget* parent) :
tr("Changes the size at which on-screen elements, including status and messages are displayed."));
dialog->registerWidgetHelp(m_ui.fullscreenUITheme, tr("Theme"), tr("Automatic"),
tr("Determines the theme to use for on-screen display elements and the Big Picture UI."));
dialog->registerWidgetHelp(
m_ui.imguiFont, tr("Font"),
m_ui.imguiFont->itemText(m_ui.imguiFont->findData(QString::fromUtf8(ImGuiManager::GetDefaultTextFontName()))),
tr("Determines the font to use for on-screen display elements and the Big Picture UI."));
dialog->registerWidgetHelp(
m_ui.imguiFixedFont, tr("Overlay Font"),
m_ui.imguiFixedFont->itemText(
m_ui.imguiFixedFont->findData(QString::fromUtf8(ImGuiManager::GetDefaultFixedFontName()))),
tr("Determines the font to use for the performance overlay."));
dialog->registerWidgetHelp(m_ui.osdMargin, tr("Display Margins"),
QStringLiteral("%1px").arg(static_cast<int>(ImGuiManager::DEFAULT_SCREEN_MARGIN)),
tr("Determines the margin between the edge of the screen and on-screen messages."));
@ -126,6 +152,17 @@ void OSDSettingsWidget::setupAdditionalUi()
m_ui.fullscreenUITheme->addItem(QtUtils::StringViewToQString(fsui_theme_names[i]),
QString::fromUtf8(fsui_theme_values[i]));
}
const std::span<const char* const> imgui_font_values = ImGuiManager::GetTextFontNames();
const std::span<const char* const> imgui_font_names = ImGuiManager::GetTextFontDisplayNames();
for (size_t i = 0; i < imgui_font_values.size(); i++)
m_ui.imguiFont->addItem(QString::fromUtf8(imgui_font_names[i]), QString::fromUtf8(imgui_font_values[i]));
const std::span<const char* const> imgui_fixed_font_values = ImGuiManager::GetFixedFontNames();
const std::span<const char* const> imgui_fixed_font_names = ImGuiManager::GetFixedFontDisplayNames();
for (size_t i = 0; i < imgui_fixed_font_values.size(); i++)
m_ui.imguiFixedFont->addItem(QString::fromUtf8(imgui_fixed_font_names[i]),
QString::fromUtf8(imgui_fixed_font_values[i]));
}
void OSDSettingsWidget::onOSDShowMessagesChanged()

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>509</width>
<height>499</height>
<width>606</width>
<height>579</height>
</rect>
</property>
<property name="windowTitle">
@ -31,7 +31,7 @@
<property name="title">
<string>Display</string>
</property>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1" columnminimumwidth="150,0">
<layout class="QGridLayout" name="gridLayout" columnstretch="0,0,0,0" columnminimumwidth="150,0,150,0">
<item row="0" column="0">
<widget class="QLabel" name="label_29">
<property name="text">
@ -39,7 +39,7 @@
</property>
</widget>
</item>
<item row="0" column="1">
<item row="0" column="1" colspan="3">
<widget class="QSpinBox" name="osdScale">
<property name="suffix">
<string>%</string>
@ -59,7 +59,7 @@
</property>
</widget>
</item>
<item row="1" column="1">
<item row="1" column="1" colspan="3">
<widget class="QSpinBox" name="osdMargin">
<property name="suffix">
<string>px</string>
@ -76,9 +76,29 @@
</property>
</widget>
</item>
<item row="2" column="1">
<item row="2" column="1" colspan="3">
<widget class="QComboBox" name="fullscreenUITheme"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Font:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QComboBox" name="imguiFont"/>
</item>
<item row="3" column="2">
<widget class="QLabel" name="label_fixedFont">
<property name="text">
<string>Overlay Font:</string>
</property>
</widget>
</item>
<item row="3" column="3">
<widget class="QComboBox" name="imguiFixedFont"/>
</item>
</layout>
</widget>
</item>

@ -2701,8 +2701,8 @@ void QtHost::UpdateFontOrder(std::string_view language)
// Why is this a thing? Because we want all glyphs to be available, but don't want to conflict
// between codepoints shared between Chinese and Japanese. Therefore we prioritize the language
// that the user has selected.
ImGuiManager::TextFontOrder font_order;
#define TF(name) ImGuiManager::TextFont::name
ImGuiManager::LanguageFontOrder font_order;
#define TF(name) ImGuiManager::LanguageFont::name
if (language == "ja")
font_order = {TF(Default), TF(Japanese), TF(Chinese), TF(Korean)};
else if (language == "ko")
@ -2710,20 +2710,20 @@ void QtHost::UpdateFontOrder(std::string_view language)
else if (language == "zh-CN")
font_order = {TF(Default), TF(Chinese), TF(Japanese), TF(Korean)};
else
font_order = ImGuiManager::GetDefaultTextFontOrder();
font_order = ImGuiManager::GetLanguageTextFontOrder();
#undef TF
if (g_core_thread)
{
Host::RunOnCoreThread([font_order]() mutable {
VideoThread::RunOnThread([font_order]() mutable { ImGuiManager::SetTextFontOrder(font_order); });
VideoThread::RunOnThread([font_order]() mutable { ImGuiManager::SetLanguageFontOrder(font_order); });
Host::ClearTranslationCache();
});
}
else
{
// Startup, safe to set directly.
ImGuiManager::SetTextFontOrder(font_order);
ImGuiManager::SetLanguageFontOrder(font_order);
Host::ClearTranslationCache();
}
}

@ -91,6 +91,8 @@ static float GetGlobalPrescale();
static float GetFixedFontWeight();
static void UpdateScale();
static void SetStyle(ImGuiStyle& style, float scale);
static u32 GetTextFontIndex();
static u32 GetFixedFontIndex();
static bool LoadFontData(Error* error);
static void ReloadFontDataIfActive();
static bool CreateFontAtlas(Error* error);
@ -118,13 +120,77 @@ static std::optional<ImGuiKey> MapHostKeyEventToImGuiKey(u32 key);
static constexpr float OSD_FADE_IN_TIME = 0.1f;
static constexpr float OSD_FADE_OUT_TIME = 0.4f;
static constexpr std::array<const char*, static_cast<size_t>(TextFont::MaxCount)> TEXT_FONT_NAMES = {{
"Roboto-VariableFont_wdth,wght.ttf", // Default
"NotoSansSC-VariableFont_wght.ttf", // Chinese
"NotoSansJP-VariableFont_wght.ttf", // Japanese
"NotoSansKR-VariableFont_wght.ttf", // Korean
static constexpr std::array<const char*, static_cast<size_t>(LanguageFont::MaxCount)> LANGUAGE_FONT_NAMES = {{
nullptr, // Default
"NotoSansSC-VariableFont_wght.ttf", // Chinese
"NotoSansJP-VariableFont_wght.ttf", // Japanese
"NotoSansKR-VariableFont_wght.ttf", // Korean
}};
static constexpr const char* FIXED_FONT_NAME = "GoogleSansCode-VariableFont_wght.ttf";
#define ENUMERATE_TEXT_FONT_NAMES(X) \
X("Roboto", "Roboto", "Roboto-VariableFont_wdth,wght.ttf") \
X("Bitcount", "Bitcount", "BitcountPropSingle-VariableFont_CRSV,ELSH,ELXP,slnt,wght.ttf") \
X("PixelifySans", "Pixelify Sans", "PixelifySans-VariableFont_wght.ttf") \
X("Handjet", "Handjet", "Handjet-VariableFont_ELGR,ELSH,wght.ttf") \
X("Orbitron", "Orbitron", "Orbitron-VariableFont_wght.ttf") \
X("Tektur", "Tektur", "Tektur-VariableFont_wdth,wght.ttf") \
X("PlusJakartaSans", "Plus Jakarta Sans", "PlusJakartaSans-VariableFont_wght.ttf") \
X("Manrope", "Manrope", "Manrope-VariableFont_wght.ttf") \
X("Jersey25", "Jersey 25", "Jersey25-Regular.ttf") \
X("VT323", "VT323", "VT323-Regular.ttf") \
X("GoogleSansCode", "Google Sans Code", "GoogleSansCode-VariableFont_wght.ttf") \
X("KodeMono", "Kode Mono", "KodeMono-VariableFont_wght.ttf") \
X("RobotoMono", "Roboto Mono", "RobotoMono-VariableFont_wght.ttf")
static constexpr const std::array TEXT_FONT_NAMES = {
#define ADD_TEXT_FONT(name, display_name, filename) name,
ENUMERATE_TEXT_FONT_NAMES(ADD_TEXT_FONT)
#undef ADD_TEXT_FONT
};
static constexpr const std::array TEXT_FONT_DISPLAY_NAMES = {
#define ADD_TEXT_FONT(name, display_name, filename) display_name,
ENUMERATE_TEXT_FONT_NAMES(ADD_TEXT_FONT)
#undef ADD_TEXT_FONT
};
static constexpr const std::array TEXT_FONT_FILENAMES = {
#define ADD_TEXT_FONT(name, display_name, filename) filename,
ENUMERATE_TEXT_FONT_NAMES(ADD_TEXT_FONT)
#undef ADD_TEXT_FONT
};
#undef ENUMERATE_TEXT_FONT_NAMES
static constexpr const char* DEFAULT_TEXT_FONT_NAME = TEXT_FONT_NAMES[0];
#define ENUMERATE_FIXED_FONT_NAMES(X) \
X("GoogleSansCode", "Google Sans Code", "GoogleSansCode-VariableFont_wght.ttf") \
X("RobotoMono", "Roboto Mono", "RobotoMono-VariableFont_wght.ttf") \
X("KodeMono", "Kode Mono", "KodeMono-VariableFont_wght.ttf") \
X("Bitcount", "Bitcount", "BitcountPropSingle-VariableFont_CRSV,ELSH,ELXP,slnt,wght.ttf")
static constexpr const std::array FIXED_FONT_NAMES = {
#define ADD_FIXED_FONT(name, display_name, filename) name,
ENUMERATE_FIXED_FONT_NAMES(ADD_FIXED_FONT)
#undef ADD_FIXED_FONT
};
static constexpr const std::array FIXED_FONT_DISPLAY_NAMES = {
#define ADD_FIXED_FONT(name, display_name, filename) display_name,
ENUMERATE_FIXED_FONT_NAMES(ADD_FIXED_FONT)
#undef ADD_FIXED_FONT
};
static constexpr const std::array FIXED_FONT_FILENAMES = {
#define ADD_FIXED_FONT(name, display_name, filename) filename,
ENUMERATE_FIXED_FONT_NAMES(ADD_FIXED_FONT)
#undef ADD_FIXED_FONT
};
#undef ENUMERATE_FIXED_FONT_NAMES
static constexpr const char* DEFAULT_FIXED_FONT_NAME = FIXED_FONT_NAMES[0];
static constexpr const char* FA_FONT_NAME = FONT_ICON_FILE_NAME_FAS;
static constexpr const char* PF_FONT_NAME = "promptfont.otf";
static constexpr const char* EMOJI_FONT_NAME = "TwitterColorEmoji-SVGinOT.ttf";
@ -172,9 +238,11 @@ struct ALIGN_TO_CACHE_LINE State
std::deque<OSDMessage> osd_active_messages;
float osd_messages_end_y = 0.0f;
TextFontOrder text_font_order = ImGuiManager::GetDefaultTextFontOrder();
LanguageFontOrder text_font_order = ImGuiManager::GetLanguageTextFontOrder();
u32 text_font_index = 0;
u32 fixed_font_index = 0;
std::array<DynamicHeapArray<u8>, static_cast<size_t>(TextFont::MaxCount)> text_fonts_data;
std::array<DynamicHeapArray<u8>, static_cast<size_t>(LanguageFont::MaxCount)> text_fonts_data;
DynamicHeapArray<u8> fixed_font_data;
DynamicHeapArray<u8> icon_fa_font_data;
DynamicHeapArray<u8> icon_pf_font_data;
@ -187,12 +255,12 @@ static State s_state;
} // namespace ImGuiManager
ImGuiManager::TextFontOrder ImGuiManager::GetDefaultTextFontOrder()
ImGuiManager::LanguageFontOrder ImGuiManager::GetLanguageTextFontOrder()
{
return {TextFont::Default, TextFont::Japanese, TextFont::Chinese, TextFont::Korean};
return {LanguageFont::Default, LanguageFont::Japanese, LanguageFont::Chinese, LanguageFont::Korean};
}
void ImGuiManager::SetTextFontOrder(const TextFontOrder& order)
void ImGuiManager::SetLanguageFontOrder(const LanguageFontOrder& order)
{
if (s_state.text_font_order == order)
return;
@ -201,8 +269,105 @@ void ImGuiManager::SetTextFontOrder(const TextFontOrder& order)
ReloadFontDataIfActive();
}
std::span<const char* const> ImGuiManager::GetTextFontNames()
{
return TEXT_FONT_NAMES;
}
std::span<const char* const> ImGuiManager::GetTextFontDisplayNames()
{
return TEXT_FONT_DISPLAY_NAMES;
}
const char* ImGuiManager::GetDefaultTextFontName()
{
return DEFAULT_TEXT_FONT_NAME;
}
u32 ImGuiManager::GetTextFontIndex()
{
const TinyString name = Core::GetBaseTinyStringSettingValue("Main", "ImGuiTextFont", DEFAULT_TEXT_FONT_NAME);
// must be a valid name
const auto it = std::ranges::find_if(TEXT_FONT_NAMES, [&name](const char* n) { return (name == n); });
if (it == TEXT_FONT_NAMES.end()) [[unlikely]]
{
ERROR_LOG("Invalid text font name: {}", name);
return 0;
}
return static_cast<u32>(std::distance(TEXT_FONT_NAMES.begin(), it));
}
void ImGuiManager::UpdateTextFont()
{
if (!IsInitialized())
return;
const u32 new_index = GetTextFontIndex();
if (new_index == s_state.text_font_index)
return;
s_state.text_font_index = new_index;
// Force the actual font data to reload.
s_state.text_fonts_data[static_cast<size_t>(LanguageFont::Default)].deallocate();
ReloadFontDataIfActive();
}
std::span<const char* const> ImGuiManager::GetFixedFontNames()
{
return FIXED_FONT_NAMES;
}
std::span<const char* const> ImGuiManager::GetFixedFontDisplayNames()
{
return FIXED_FONT_DISPLAY_NAMES;
}
const char* ImGuiManager::GetDefaultFixedFontName()
{
return DEFAULT_FIXED_FONT_NAME;
}
u32 ImGuiManager::GetFixedFontIndex()
{
const TinyString name = Core::GetBaseTinyStringSettingValue("Main", "ImGuiFixedFont", DEFAULT_FIXED_FONT_NAME);
// must be a valid name
const auto it = std::ranges::find_if(FIXED_FONT_NAMES, [&name](const char* n) { return (name == n); });
if (it == FIXED_FONT_NAMES.end()) [[unlikely]]
{
ERROR_LOG("Invalid fixed font name: {}", name);
return 0;
}
return static_cast<u32>(std::distance(FIXED_FONT_NAMES.begin(), it));
}
void ImGuiManager::UpdateFixedFont()
{
if (!IsInitialized())
return;
const u32 new_index = GetFixedFontIndex();
if (new_index == s_state.fixed_font_index)
return;
s_state.fixed_font_index = new_index;
// Force the actual font data to reload.
s_state.fixed_font_data.deallocate();
ReloadFontDataIfActive();
}
bool ImGuiManager::Initialize(Error* error)
{
s_state.text_font_index = GetTextFontIndex();
s_state.fixed_font_index = GetFixedFontIndex();
if (!LoadFontData(error))
{
Error::AddPrefix(error, "Failed to load font data: ");
@ -696,14 +861,16 @@ bool ImGuiManager::LoadFontData(Error* error)
};
// only load used text fonts, that way we don't waste memory on mini
for (const TextFont text_font : s_state.text_font_order)
for (const LanguageFont language_font : s_state.text_font_order)
{
const u32 index = static_cast<u32>(text_font);
const u32 index = static_cast<u32>(language_font);
if (!s_state.text_fonts_data[index].empty())
continue;
std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile(font_resource_name(TEXT_FONT_NAMES[index]), true, error);
std::optional<DynamicHeapArray<u8>> font_data = Host::ReadResourceFile(
font_resource_name((language_font != LanguageFont::Default) ? LANGUAGE_FONT_NAMES[index] :
TEXT_FONT_FILENAMES[s_state.text_font_index]),
true, error);
if (!font_data.has_value())
return false;
@ -713,7 +880,7 @@ bool ImGuiManager::LoadFontData(Error* error)
if (s_state.fixed_font_data.empty())
{
std::optional<DynamicHeapArray<u8>> font_data =
Host::ReadResourceFile(font_resource_name(FIXED_FONT_NAME), true, error);
Host::ReadResourceFile(font_resource_name(FIXED_FONT_FILENAMES[s_state.fixed_font_index]), true, error);
if (!font_data.has_value())
return false;
@ -768,8 +935,8 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
// First text font has to be added before the icon fonts.
// Remaining fonts are added after the icon font, otherwise the wrong glyphs will be used in the UI.
const TextFont first_font = s_state.text_font_order.front();
StringUtil::Strlcpy(text_cfg.Name, TEXT_FONT_NAMES[static_cast<size_t>(first_font)], std::size(text_cfg.Name));
const LanguageFont first_font = s_state.text_font_order.front();
StringUtil::Strlcpy(text_cfg.Name, "TextFont", std::size(text_cfg.Name));
auto& first_font_data = s_state.text_fonts_data[static_cast<size_t>(first_font)];
Assert(!first_font_data.empty());
s_state.text_font =
@ -823,13 +990,12 @@ bool ImGuiManager::CreateFontAtlas(Error* error)
text_cfg.MergeMode = true;
for (size_t i = 1; i < s_state.text_font_order.size(); i++)
{
const TextFont text_font_idx = s_state.text_font_order[i];
const LanguageFont text_font_idx = s_state.text_font_order[i];
if (text_font_idx == first_font)
continue;
auto& font_data = s_state.text_fonts_data[static_cast<size_t>(text_font_idx)];
Assert(!font_data.empty());
StringUtil::Strlcpy(text_cfg.Name, "TextFont-", std::size(text_cfg.Name));
if (!ImGui::GetIO().Fonts->AddFontFromMemoryTTF(font_data.data(), static_cast<int>(font_data.size()),
default_text_size, DEFAULT_TEXT_FONT_WEIGHT, &text_cfg))
{
@ -862,16 +1028,12 @@ void ImGuiManager::ReloadFontDataIfActive()
if (!s_state.imgui_context)
return;
ImGui::EndFrame();
Error error;
if (!CreateFontAtlas(&error)) [[unlikely]]
if (!LoadFontData(&error) || !CreateFontAtlas(&error)) [[unlikely]]
{
VideoThread::ReportFatalErrorAndShutdown(fmt::format("Failed to recreate font atlas:\n{}", error.GetDescription()));
return;
}
NewFrame(Timer::GetCurrentValue());
}
float ImGuiManager::GetOSDMessageDuration(OSDMessageType type)
@ -1322,7 +1484,8 @@ void Host::AddIconOSDMessage(OSDMessageType type, std::string key, const char* i
{
const std::string_view icon_sv = icon;
const OSDMessageIconType icon_type = ImGuiManager::GetOSDMessageIconType(icon_sv);
ImGuiManager::AddOSDMessage(type, std::move(key), icon_type, std::string(icon_sv), std::move(title), std::move(message));
ImGuiManager::AddOSDMessage(type, std::move(key), icon_type, std::string(icon_sv), std::move(title),
std::move(message));
}
void Host::AddIconOSDMessage(OSDMessageType type, std::string key, std::string icon, std::string title,

@ -81,7 +81,7 @@ namespace ImGuiManager {
using WCharType = u32;
enum class TextFont : u8
enum class LanguageFont : u8
{
Default,
Chinese,
@ -90,7 +90,7 @@ enum class TextFont : u8
MaxCount
};
using TextFontOrder = std::array<TextFont, static_cast<size_t>(TextFont::MaxCount)>;
using LanguageFontOrder = std::array<LanguageFont, static_cast<size_t>(LanguageFont::MaxCount)>;
/// Default size for screen margins.
#ifndef __ANDROID__
@ -99,16 +99,28 @@ inline constexpr float DEFAULT_SCREEN_MARGIN = 10.0f;
inline constexpr float DEFAULT_SCREEN_MARGIN = 16.0f;
#endif
/// Sets the order for text fonts.
TextFontOrder GetDefaultTextFontOrder();
void SetTextFontOrder(const TextFontOrder& order);
/// Initializes ImGui, creates fonts, etc.
bool Initialize(Error* error);
/// Frees all ImGui resources.
void Shutdown();
/// Sets the order for text fonts.
LanguageFontOrder GetLanguageTextFontOrder();
void SetLanguageFontOrder(const LanguageFontOrder& order);
/// Returns a list of possible font names.
std::span<const char* const> GetTextFontNames();
std::span<const char* const> GetTextFontDisplayNames();
const char* GetDefaultTextFontName();
void UpdateTextFont();
/// Returns a list of possible fixed-width (overlay) font names.
std::span<const char* const> GetFixedFontNames();
std::span<const char* const> GetFixedFontDisplayNames();
const char* GetDefaultFixedFontName();
void UpdateFixedFont();
bool CreateGPUResources(Error* error);
void DestroyGPUResources();

Loading…
Cancel
Save