Add font configuration (to be able to use non-latin languages)

This commit is contained in:
Alexis Murzeau 2022-08-22 23:53:50 +02:00
parent aa58379c56
commit 95ed735269
8 changed files with 108 additions and 3 deletions

View File

@ -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

View File

@ -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();
}
}

View File

@ -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];
};

View File

@ -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());
}

View File

@ -92,6 +92,7 @@ struct optionsStruct
bool DebugOverlayCollisionMask;
bool DebugOverlaySprites;
bool DebugOverlaySounds;
std::string FontFileName;
};
struct ControlRef

View File

@ -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<ImWchar>* 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,

View File

@ -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<ImWchar>* ranges);
};

View File

@ -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<ImWchar> 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<const char*> 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();