From 95ed735269944a878d927233431022497f04be88 Mon Sep 17 00:00:00 2001 From: Alexis Murzeau Date: Mon, 22 Aug 2022 23:53:50 +0200 Subject: [PATCH] Add font configuration (to be able to use non-latin languages) --- CMakeLists.txt | 2 ++ SpaceCadetPinball/font_selection.cpp | 50 ++++++++++++++++++++++++++++ SpaceCadetPinball/font_selection.h | 11 ++++++ SpaceCadetPinball/options.cpp | 2 ++ SpaceCadetPinball/options.h | 1 + SpaceCadetPinball/translations.cpp | 16 +++++++++ SpaceCadetPinball/translations.h | 1 + SpaceCadetPinball/winmain.cpp | 28 ++++++++++++++-- 8 files changed, 108 insertions(+), 3 deletions(-) create mode 100644 SpaceCadetPinball/font_selection.cpp create mode 100644 SpaceCadetPinball/font_selection.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a47e16c..3f2be7a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,8 @@ set(SOURCE_FILES SpaceCadetPinball/control.h SpaceCadetPinball/EmbeddedData.cpp SpaceCadetPinball/EmbeddedData.h + SpaceCadetPinball/font_selection.cpp + SpaceCadetPinball/font_selection.h SpaceCadetPinball/fullscrn.cpp SpaceCadetPinball/fullscrn.h SpaceCadetPinball/gdrv.cpp diff --git a/SpaceCadetPinball/font_selection.cpp b/SpaceCadetPinball/font_selection.cpp new file mode 100644 index 0000000..3b6a60e --- /dev/null +++ b/SpaceCadetPinball/font_selection.cpp @@ -0,0 +1,50 @@ +#include "pch.h" +#include "font_selection.h" + +#include "options.h" +#include "pinball.h" +#include "score.h" +#include "winmain.h" + +static const char* popupName = "Font Selection"; +bool font_selection::ShowDialog = false; +char font_selection::DialogInputBuffer[512]; + +void font_selection::show_dialog() +{ + ShowDialog = true; +} + +void font_selection::RenderDialog() +{ + if (ShowDialog == true) + { + strncpy(DialogInputBuffer, options::Options.FontFileName.c_str(), sizeof(DialogInputBuffer)); + ShowDialog = false; + if (!ImGui::IsPopupOpen(popupName)) + { + ImGui::OpenPopup(popupName); + } + } + + bool unused_open = true; + if (ImGui::BeginPopupModal(popupName, &unused_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Font file to use: "); + ImGui::SameLine(); + ImGui::InputText("", DialogInputBuffer, IM_ARRAYSIZE(DialogInputBuffer)); + + if (ImGui::Button(pinball::get_rc_string(translation_id_e::HIGHSCORES_Ok))) + { + options::Options.FontFileName = DialogInputBuffer; + ImGui::CloseCurrentPopup(); + winmain::Restart(); + } + + ImGui::SameLine(); + if (ImGui::Button(pinball::get_rc_string(translation_id_e::HIGHSCORES_Cancel))) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); + } +} diff --git a/SpaceCadetPinball/font_selection.h b/SpaceCadetPinball/font_selection.h new file mode 100644 index 0000000..fc90afa --- /dev/null +++ b/SpaceCadetPinball/font_selection.h @@ -0,0 +1,11 @@ +#pragma once + +class font_selection +{ +public: + static void show_dialog(); + static void RenderDialog(); +private: + static bool ShowDialog; + static char DialogInputBuffer[512]; +}; diff --git a/SpaceCadetPinball/options.cpp b/SpaceCadetPinball/options.cpp index 04ace26..9915ee9 100644 --- a/SpaceCadetPinball/options.cpp +++ b/SpaceCadetPinball/options.cpp @@ -115,6 +115,7 @@ void options::InitPrimary() Options.DebugOverlaySprites = get_int("Debug Overlay Sprites", true); Options.DebugOverlaySounds = get_int("Debug Overlay Sounds", true); translations::set_current_language(get_string("Language", translations::get_current_language()).c_str()); + Options.FontFileName = get_string("FontFileName", ""); } void options::InitSecondary() @@ -164,6 +165,7 @@ void options::uninit() set_int("Debug Overlay Sprites", Options.DebugOverlaySprites); set_int("Debug Overlay Sounds", Options.DebugOverlaySounds); set_string("Language", translations::get_current_language()); + set_string("FontFileName", Options.FontFileName.c_str()); } diff --git a/SpaceCadetPinball/options.h b/SpaceCadetPinball/options.h index d03b82c..7c8479e 100644 --- a/SpaceCadetPinball/options.h +++ b/SpaceCadetPinball/options.h @@ -92,6 +92,7 @@ struct optionsStruct bool DebugOverlayCollisionMask; bool DebugOverlaySprites; bool DebugOverlaySounds; + std::string FontFileName; }; struct ControlRef diff --git a/SpaceCadetPinball/translations.cpp b/SpaceCadetPinball/translations.cpp index ace1a4b..fe58e7f 100644 --- a/SpaceCadetPinball/translations.cpp +++ b/SpaceCadetPinball/translations.cpp @@ -115,6 +115,22 @@ const char* translations::get_translation(translation_id_e id) return translated_strings[id][current_language]; } +void translations::get_glyph_range(ImVector* ranges) +{ + ImFontGlyphRangesBuilder builder; + + for(int i = 0; i < (int)translation_id_e::NUMBER; i++) { + const char* translation = get_translation((translation_id_e)i); + if(translation) + { + builder.AddText(translation); + } + } + + builder.AddRanges(ImGui::GetIO().Fonts->GetGlyphRangesDefault()); + builder.BuildRanges(ranges); +} + namespace { const InitializedArray< translation_id_e, diff --git a/SpaceCadetPinball/translations.h b/SpaceCadetPinball/translations.h index 41249df..c52d6cb 100644 --- a/SpaceCadetPinball/translations.h +++ b/SpaceCadetPinball/translations.h @@ -267,4 +267,5 @@ public: static const char* get_translation(translation_id_e id); static void set_current_language(const char* language_name); static const char* get_current_language(); + static void get_glyph_range(ImVector* ranges); }; diff --git a/SpaceCadetPinball/winmain.cpp b/SpaceCadetPinball/winmain.cpp index 1b5a1bb..023a87f 100644 --- a/SpaceCadetPinball/winmain.cpp +++ b/SpaceCadetPinball/winmain.cpp @@ -10,6 +10,7 @@ #include "render.h" #include "Sound.h" #include "translations.h" +#include "font_selection.h" SDL_Window* winmain::MainWindow = nullptr; SDL_Renderer* winmain::Renderer = nullptr; @@ -107,9 +108,6 @@ int winmain::WinMain(LPCSTR lpCmdLine) ImGui::StyleColorsDark(); ImGuiIO& io = ImGui::GetIO(); ImIO = &io; - // ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend - ImGui_ImplSDL2_InitForOpenGL(window, nullptr); - io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad; auto prefPath = SDL_GetPrefPath(nullptr, "SpaceCadetPinball"); auto iniPath = std::string(prefPath) + "imgui_pb.ini"; @@ -118,6 +116,25 @@ int winmain::WinMain(LPCSTR lpCmdLine) // First step: just load the options options::InitPrimary(); + if(!Options.FontFileName.empty()) { + ImGuiSDL::Deinitialize(); + io.Fonts->Clear(); + ImVector ranges; + translations::get_glyph_range(&ranges); + ImFontConfig fontConfig; + fontConfig.OversampleV = 2; + fontConfig.OversampleH = 8; + + io.Fonts->AddFontFromFileTTF(Options.FontFileName.c_str(), 13.f, &fontConfig, ranges.Data); + io.Fonts->Build(); + + ImGuiSDL::Initialize(renderer, 0, 0); + } + + // ImGui_ImplSDL2_Init is private, we are not actually using ImGui OpenGl backend + ImGui_ImplSDL2_InitForOpenGL(window, nullptr); + io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard | ImGuiConfigFlags_NavEnableGamepad; + // Data search order: WD, executable path, user pref path, platform specific paths. auto basePath = SDL_GetBasePath(); std::vector searchPaths @@ -501,6 +518,10 @@ void winmain::RenderUi() if (ImGui::BeginMenu("Graphics")) { + if (ImGui::MenuItem("Change Font")) + { + font_selection::show_dialog(); + } if (ImGui::MenuItem("Uniform Scaling", nullptr, Options.UniformScaling)) { options::toggle(Menu1::WindowUniformScale); @@ -670,6 +691,7 @@ void winmain::RenderUi() a_dialog(); high_score::RenderHighScoreDialog(); + font_selection::RenderDialog(); if (ShowSpriteViewer) render::SpriteViewer(&ShowSpriteViewer); options::RenderControlDialog();