|
21 | 21 | #include "xenia/ui/ui_event.h"
|
22 | 22 | #include "xenia/ui/window.h"
|
23 | 23 |
|
| 24 | +#if XE_PLATFORM_WIN32 |
| 25 | +#include <ShlObj_core.h> |
| 26 | +#endif |
| 27 | + |
| 28 | +DEFINE_path( |
| 29 | + custom_font_path, "", |
| 30 | + "Allows user to load custom font and use it instead of default one.", |
| 31 | + "General"); |
| 32 | + |
24 | 33 | namespace xe {
|
25 | 34 | namespace ui {
|
26 | 35 |
|
@@ -98,38 +107,7 @@ void ImGuiDrawer::Initialize() {
|
98 | 107 | internal_state_ = ImGui::CreateContext();
|
99 | 108 | ImGui::SetCurrentContext(internal_state_);
|
100 | 109 |
|
101 |
| - auto& io = ImGui::GetIO(); |
102 |
| - |
103 |
| - // TODO(gibbed): disable imgui.ini saving for now, |
104 |
| - // imgui assumes paths are char* so we can't throw a good path at it on |
105 |
| - // Windows. |
106 |
| - io.IniFilename = nullptr; |
107 |
| - |
108 |
| - // Setup the font glyphs. |
109 |
| - ImFontConfig font_config; |
110 |
| - font_config.OversampleH = font_config.OversampleV = 1; |
111 |
| - font_config.PixelSnapH = true; |
112 |
| - static const ImWchar font_glyph_ranges[] = { |
113 |
| - 0x0020, |
114 |
| - 0x00FF, // Basic Latin + Latin Supplement |
115 |
| - 0, |
116 |
| - }; |
117 |
| - io.Fonts->AddFontFromMemoryCompressedBase85TTF( |
118 |
| - kProggyTinyCompressedDataBase85, 10.0f, &font_config, font_glyph_ranges); |
119 |
| - // TODO(benvanik): jp font on other platforms? |
120 |
| - // https://github.com/Koruri/kibitaki looks really good, but is 1.5MiB. |
121 |
| - const char* jp_font_path = "C:\\Windows\\Fonts\\msgothic.ttc"; |
122 |
| - if (std::filesystem::exists(jp_font_path)) { |
123 |
| - ImFontConfig jp_font_config; |
124 |
| - jp_font_config.MergeMode = true; |
125 |
| - jp_font_config.OversampleH = jp_font_config.OversampleV = 1; |
126 |
| - jp_font_config.PixelSnapH = true; |
127 |
| - jp_font_config.FontNo = 0; |
128 |
| - io.Fonts->AddFontFromFileTTF(jp_font_path, 12.0f, &jp_font_config, |
129 |
| - io.Fonts->GetGlyphRangesJapanese()); |
130 |
| - } else { |
131 |
| - XELOGW("Unable to load Japanese font; JP characters will be boxes"); |
132 |
| - } |
| 110 | + InitializeFonts(); |
133 | 111 |
|
134 | 112 | auto& style = ImGui::GetStyle();
|
135 | 113 | style.ScrollbarRounding = 0;
|
@@ -218,6 +196,74 @@ std::optional<ImGuiKey> ImGuiDrawer::VirtualKeyToImGuiKey(VirtualKey vkey) {
|
218 | 196 | }
|
219 | 197 | }
|
220 | 198 |
|
| 199 | +void ImGuiDrawer::InitializeFonts() { |
| 200 | + auto& io = ImGui::GetIO(); |
| 201 | + |
| 202 | + const float default_font_size = 12.0f; |
| 203 | + // TODO(gibbed): disable imgui.ini saving for now, |
| 204 | + // imgui assumes paths are char* so we can't throw a good path at it on |
| 205 | + // Windows. |
| 206 | + io.IniFilename = nullptr; |
| 207 | + |
| 208 | + // Setup the font glyphs. |
| 209 | + ImFontConfig font_config; |
| 210 | + font_config.OversampleH = font_config.OversampleV = 2; |
| 211 | + font_config.PixelSnapH = true; |
| 212 | + |
| 213 | + // https://jrgraphix.net/r/Unicode/ |
| 214 | + static const ImWchar font_glyph_ranges[] = { |
| 215 | + 0x0020, 0x00FF, // Basic Latin + Latin Supplement |
| 216 | + 0x2000, 0x206F, // General Punctuation |
| 217 | + 0, |
| 218 | + }; |
| 219 | + |
| 220 | + if (!cvars::custom_font_path.empty() && |
| 221 | + std::filesystem::exists(cvars::custom_font_path)) { |
| 222 | + const std::string font_path = xe::path_to_utf8(cvars::custom_font_path); |
| 223 | + ImFont* font = io.Fonts->AddFontFromFileTTF( |
| 224 | + font_path.c_str(), default_font_size, &font_config, font_glyph_ranges); |
| 225 | + |
| 226 | + io.Fonts->Build(); |
| 227 | + // Something went wrong while loading custom font. Probably corrupted. |
| 228 | + if (!font->IsLoaded()) { |
| 229 | + XELOGE("Failed to load custom font: {}", font_path); |
| 230 | + io.Fonts->Clear(); |
| 231 | + } |
| 232 | + } |
| 233 | + |
| 234 | + if (io.Fonts->Fonts.empty()) { |
| 235 | + io.Fonts->AddFontFromMemoryCompressedBase85TTF( |
| 236 | + kProggyTinyCompressedDataBase85, default_font_size, &font_config, |
| 237 | + io.Fonts->GetGlyphRangesDefault()); |
| 238 | + } |
| 239 | + |
| 240 | + // TODO(benvanik): jp font on other platforms? |
| 241 | +#if XE_PLATFORM_WIN32 |
| 242 | + PWSTR fonts_dir; |
| 243 | + HRESULT result = SHGetKnownFolderPath(FOLDERID_Fonts, 0, NULL, &fonts_dir); |
| 244 | + if (FAILED(result)) { |
| 245 | + XELOGW("Unable to find Windows fonts directory"); |
| 246 | + return; |
| 247 | + } |
| 248 | + |
| 249 | + std::filesystem::path jp_font_path = std::wstring(fonts_dir); |
| 250 | + jp_font_path.append("msgothic.ttc"); |
| 251 | + if (std::filesystem::exists(jp_font_path)) { |
| 252 | + ImFontConfig jp_font_config; |
| 253 | + jp_font_config.MergeMode = true; |
| 254 | + jp_font_config.OversampleH = jp_font_config.OversampleV = 2; |
| 255 | + jp_font_config.PixelSnapH = true; |
| 256 | + jp_font_config.FontNo = 0; |
| 257 | + io.Fonts->AddFontFromFileTTF(xe::path_to_utf8(jp_font_path).c_str(), |
| 258 | + default_font_size, &jp_font_config, |
| 259 | + io.Fonts->GetGlyphRangesJapanese()); |
| 260 | + } else { |
| 261 | + XELOGW("Unable to load Japanese font; JP characters will be boxes"); |
| 262 | + } |
| 263 | + CoTaskMemFree(static_cast<void*>(fonts_dir)); |
| 264 | +#endif |
| 265 | +} |
| 266 | + |
221 | 267 | void ImGuiDrawer::SetupFontTexture() {
|
222 | 268 | if (font_texture_ || !immediate_drawer_) {
|
223 | 269 | return;
|
|
0 commit comments