From e256efa6416cc99f5ea124fb0db78c44fd895e16 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 21 Mar 2022 23:36:17 -0500 Subject: [PATCH] GUI: add option to load Japanese chars issue #52 --- src/gui/fonts.h | 5 +++ src/gui/gui.cpp | 5 +++ src/gui/gui.h | 3 ++ src/gui/settings.cpp | 77 ++++++++++++++++++++++++++++++++++---------- 4 files changed, 73 insertions(+), 17 deletions(-) diff --git a/src/gui/fonts.h b/src/gui/fonts.h index 8f808a061..a0a42d251 100644 --- a/src/gui/fonts.h +++ b/src/gui/fonts.h @@ -46,3 +46,8 @@ extern const unsigned int builtinFontLen[]; extern const unsigned int* builtinFontM[]; extern const unsigned int builtinFontMLen[]; #endif + +// "(Glimmer of hope: the atlas system will be rewritten in the future to make scaling more flexible.)"" +// not just that. somebody rewrite it already so I can load these glyphs at run-time and support +// all languages at once, instead of having to load Unifont's 65k+ characters and blow the GPU up in the +// process! \ No newline at end of file diff --git a/src/gui/gui.cpp b/src/gui/gui.cpp index 4af736eeb..ddb7433d4 100644 --- a/src/gui/gui.cpp +++ b/src/gui/gui.cpp @@ -2699,6 +2699,11 @@ FurnaceGUI::FurnaceGUI(): aboutSin(0), aboutHue(0.0f), backupTimer(15.0), + mainFont(NULL), + iconFont(NULL), + patFont(NULL), + bigFont(NULL), + fontRange(NULL), curIns(0), curWave(0), curSample(0), diff --git a/src/gui/gui.h b/src/gui/gui.h index bfecdbb13..7433750ea 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -530,6 +530,7 @@ class FurnaceGUI { ImFont* iconFont; ImFont* patFont; ImFont* bigFont; + ImWchar* fontRange; ImVec4 uiColors[GUI_COLOR_MAX]; ImVec4 volColors[128]; ImU32 pitchGrad[256]; @@ -584,6 +585,7 @@ class FurnaceGUI { int roundedWindows; int roundedButtons; int roundedMenus; + int loadJapanese; unsigned int maxUndoSteps; String mainFontPath; String patFontPath; @@ -633,6 +635,7 @@ class FurnaceGUI { roundedWindows(1), roundedButtons(1), roundedMenus(0), + loadJapanese(0), maxUndoSteps(100), mainFontPath(""), patFontPath(""), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index a3fd347d6..5348bfa06 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -346,6 +346,19 @@ void FurnaceGUI::drawSettings() { if (settings.patFontSize>96) settings.patFontSize=96; } + bool loadJapaneseB=settings.loadJapanese; + if (ImGui::Checkbox("Display Japanese characters",&loadJapaneseB)) { + settings.loadJapanese=loadJapaneseB; + } + if (ImGui::IsItemHovered()) { + ImGui::SetTooltip( + "Only toggle this option if you have enough graphics memory.\n" + "This is a temporary solution until dynamic font atlas is implemented in Dear ImGui.\n\n" + "このオプションは、十分なグラフィックメモリがある場合にのみ切り替えてください。\n" + "これは、Dear ImGuiにダイナミックフォントアトラスが実装されるまでの一時的な解決策です。" + ); + } + ImGui::Separator(); ImGui::Text("Orders row number format:"); @@ -927,6 +940,7 @@ void FurnaceGUI::syncSettings() { settings.roundedWindows=e->getConfInt("roundedWindows",1); settings.roundedButtons=e->getConfInt("roundedButtons",1); settings.roundedMenus=e->getConfInt("roundedMenus",0); + settings.loadJapanese=e->getConfInt("loadJapanese",0); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.patFontSize,2,96); @@ -970,6 +984,7 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.roundedWindows,0,1); clampSetting(settings.roundedButtons,0,1); clampSetting(settings.roundedMenus,0,1); + clampSetting(settings.loadJapanese,0,1); // keybinds LOAD_KEYBIND(GUI_ACTION_OPEN,FURKMOD_CMD|SDLK_o); @@ -1175,6 +1190,7 @@ void FurnaceGUI::commitSettings() { e->setConf("roundedWindows",settings.roundedWindows); e->setConf("roundedButtons",settings.roundedButtons); e->setConf("roundedMenus",settings.roundedMenus); + e->setConf("loadJapanese",settings.loadJapanese); PUT_UI_COLOR(GUI_COLOR_BACKGROUND); PUT_UI_COLOR(GUI_COLOR_FRAME_BACKGROUND); @@ -1710,7 +1726,24 @@ void FurnaceGUI::applyUISettings() { } // set to 800 for now due to problems with unifont - static const ImWchar loadEverything[]={0x20,0x800,0}; + static const ImWchar upTo800[]={0x20,0x7e,0xa0,0x800,0}; + ImFontGlyphRangesBuilder range; + ImVector outRange; + + range.AddRanges(upTo800); + if (settings.loadJapanese) { + range.AddRanges(ImGui::GetIO().Fonts->GetGlyphRangesJapanese()); + } + // I'm terribly sorry + range.UsedChars[0x80>>5]=0; + + range.BuildRanges(&outRange); + if (fontRange!=NULL) delete[] fontRange; + fontRange=new ImWchar[outRange.size()]; + int index=0; + for (ImWchar& i: outRange) { + fontRange[index++]=i; + } if (settings.mainFont<0 || settings.mainFont>6) settings.mainFont=0; if (settings.patFont<0 || settings.patFont>6) settings.patFont=0; @@ -1724,22 +1757,25 @@ void FurnaceGUI::applyUISettings() { settings.patFont=0; } + ImFontConfig fc1; + fc1.MergeMode=true; + if (settings.mainFont==6) { // custom font - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.mainFontPath.c_str(),e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.mainFontPath.c_str(),e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { logW("could not load UI font! reverting to default font\n"); settings.mainFont=0; - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { logE("could not load UI font! falling back to Proggy Clean.\n"); mainFont=ImGui::GetIO().Fonts->AddFontDefault(); } } } else if (settings.mainFont==5) { // system font - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_1,e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_2,e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_3,e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_1,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_2,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_FONT_PATH_3,e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { logW("could not load UI font! reverting to default font\n"); settings.mainFont=0; - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { logE("could not load UI font! falling back to Proggy Clean.\n"); mainFont=ImGui::GetIO().Fonts->AddFontDefault(); } @@ -1747,17 +1783,21 @@ void FurnaceGUI::applyUISettings() { } } } else { - if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFont[settings.mainFont],builtinFontLen[settings.mainFont],e->getConfInt("mainFontSize",18)*dpiScale,NULL,fontRange))==NULL) { logE("could not load UI font! falling back to Proggy Clean.\n"); mainFont=ImGui::GetIO().Fonts->AddFontDefault(); } } + // two fallback fonts + mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(font_liberationSans_compressed_data,font_liberationSans_compressed_size,e->getConfInt("mainFontSize",18)*dpiScale,&fc1,fontRange); + mainFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(font_unifont_compressed_data,font_unifont_compressed_size,e->getConfInt("mainFontSize",18)*dpiScale,&fc1,fontRange); + ImFontConfig fc; fc.MergeMode=true; fc.GlyphMinAdvanceX=e->getConfInt("iconSize",16)*dpiScale; - static const ImWchar fontRange[]={ICON_MIN_FA,ICON_MAX_FA,0}; - if ((iconFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(iconFont_compressed_data,iconFont_compressed_size,e->getConfInt("iconSize",16)*dpiScale,&fc,fontRange))==NULL) { + static const ImWchar fontRangeIcon[]={ICON_MIN_FA,ICON_MAX_FA,0}; + if ((iconFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(iconFont_compressed_data,iconFont_compressed_size,e->getConfInt("iconSize",16)*dpiScale,&fc,fontRangeIcon))==NULL) { logE("could not load icon font!\n"); } if (settings.mainFontSize==settings.patFontSize && settings.patFont<5 && builtinFontM[settings.patFont]==builtinFont[settings.mainFont]) { @@ -1765,21 +1805,21 @@ void FurnaceGUI::applyUISettings() { patFont=mainFont; } else { if (settings.patFont==6) { // custom font - if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.patFontPath.c_str(),e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(settings.patFontPath.c_str(),e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { logW("could not load pattern font! reverting to default font\n"); settings.patFont=0; - if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { logE("could not load pattern font! falling back to Proggy Clean.\n"); patFont=ImGui::GetIO().Fonts->AddFontDefault(); } } } else if (settings.patFont==5) { // system font - if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_1,e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { - if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_2,e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { - if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_3,e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_1,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_2,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromFileTTF(SYSTEM_PAT_FONT_PATH_3,e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { logW("could not load pattern font! reverting to default font\n"); settings.patFont=0; - if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { logE("could not load pattern font! falling back to Proggy Clean.\n"); patFont=ImGui::GetIO().Fonts->AddFontDefault(); } @@ -1787,7 +1827,7 @@ void FurnaceGUI::applyUISettings() { } } } else { - if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,loadEverything))==NULL) { + if ((patFont=ImGui::GetIO().Fonts->AddFontFromMemoryCompressedTTF(builtinFontM[settings.patFont],builtinFontMLen[settings.patFont],e->getConfInt("patFontSize",18)*dpiScale,NULL,upTo800))==NULL) { logE("could not load pattern font!\n"); patFont=ImGui::GetIO().Fonts->AddFontDefault(); } @@ -1797,6 +1837,9 @@ void FurnaceGUI::applyUISettings() { logE("could not load big UI font!\n"); } + mainFont->FallbackChar='?'; + mainFont->DotChar='.'; + // TODO: allow changing these colors. ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeDir,"",ImVec4(0.0f,1.0f,1.0f,1.0f),ICON_FA_FOLDER_O); ImGuiFileDialog::Instance()->SetFileStyle(IGFD_FileStyleByTypeFile,"",ImVec4(0.7f,0.7f,0.7f,1.0f),ICON_FA_FILE_O);