From 80c9795773ea1044381be924fb3fd6ec93fd843a Mon Sep 17 00:00:00 2001 From: tildearrow Date: Mon, 16 Oct 2023 06:14:44 -0500 Subject: [PATCH] more FreeType work --- CMakeLists.txt | 7 +- README.md | 9 +- extern/imgui_patched/imconfig_fur.h | 6 +- src/gui/gui.h | 10 +++ src/gui/settings.cpp | 134 +++++++++++++++++++++++++++- 5 files changed, 159 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a87965389..e6a1e9cb0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -95,7 +95,7 @@ option(WITH_RENDER_SDL "Whether to build with the SDL_Renderer render backend." option(WITH_RENDER_OPENGL "Whether to build with the OpenGL render backend." ${WITH_RENDER_OPENGL_DEFAULT}) option(WITH_RENDER_DX11 "Whether to build with the DirectX 11 render backend." ${WITH_RENDER_DX11_DEFAULT}) option(USE_GLES "Use OpenGL ES for the OpenGL render backend." ${USE_GLES_DEFAULT}) -option(USE_FREETYPE "Use FreeType for font rendering." OFF) +option(USE_FREETYPE "Use FreeType for font rendering." ON) option(SYSTEM_FFTW "Use a system-installed version of FFTW instead of the vendored one" OFF) option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF) option(SYSTEM_FREETYPE "Use a system-installed version of FreeType instead of the vendored one" OFF) @@ -214,6 +214,11 @@ if (BUILD_GUI AND USE_FREETYPE) endif() message(STATUS "Using system-installed FreeType") else() + set(FT_DISABLE_BROTLI ON CACHE BOOL "one" FORCE) + set(FT_DISABLE_BZIP2 ON CACHE BOOL "two" FORCE) + set(FT_DISABLE_HARFBUZZ ON CACHE BOOL "three" FORCE) + set(FT_DISABLE_PNG ON CACHE BOOL "four" FORCE) + set(FT_DISABLE_ZLIB ON CACHE BOOL "five" FORCE) add_subdirectory(extern/freetype EXCLUDE_FROM_ALL) list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/freetype/include) list(APPEND DEPENDENCIES_LIBRARIES freetype) diff --git a/README.md b/README.md index 2c9e0e861..9c45c9f44 100644 --- a/README.md +++ b/README.md @@ -254,7 +254,8 @@ Available options: | `USE_SDL2` | `ON` | Build with SDL2 (required to build with GUI) | | `USE_SNDFILE` | `ON` | Build with libsndfile (required in order to work with audio files) | | `USE_BACKWARD` | `ON` | Use backward-cpp to print a backtrace on crash/abort | -| `WITH_JACK` | `ON` if system-installed JACK detected, otherwise `OFF` | Whether to build with JACK support. Auto-detects if JACK is available | +| `USE_FREETYPE` | `OFF` | Build with FreeType support | +| `WITH_JACK` | auto\* | Whether to build with JACK support. Auto-detects if JACK is available | | `WITH_PORTAUDIO` | `ON` | Whether to build with PortAudio. | | `SYSTEM_FFTW` | `OFF` | Use a system-installed version of FFTW instead of the vendored one | | `SYSTEM_FMT` | `OFF` | Use a system-installed version of fmt instead of the vendored one | @@ -262,12 +263,16 @@ Available options: | `SYSTEM_RTMIDI` | `OFF` | Use a system-installed version of RtMidi instead of the vendored one | | `SYSTEM_ZLIB` | `OFF` | Use a system-installed version of zlib instead of the vendored one | | `SYSTEM_SDL2` | `OFF` | Use a system-installed version of SDL2 instead of the vendored one | +| `SYSTEM_FREETYPE` | `OFF` | Use a system-installed version of SDL2 instead of the vendored one | | `SUPPORT_XP` | `OFF` | Build a Windows XP-compatible binary | -| `WARNINGS_ARE_ERRORS` | `OFF` (but consider enabling this & reporting any errors that arise from it!) | Whether warnings in furnace's C++ code should be treated as errors | +| `WARNINGS_ARE_ERRORS` | `OFF`\*\* | Whether warnings in furnace's C++ code should be treated as errors | | `WITH_DEMOS` | `ON` | Install demo songs on `make install` | | `WITH_INSTRUMENTS` | `ON` | Install demo instruments on `make install` | | `WITH_WAVETABLES` | `ON` | Install wavetables on `make install` | +(\*) `ON` if system-installed JACK detected, otherwise `OFF` +(\*\*) but consider enabling this & reporting any errors that arise from it! + ## CMake Error if it says something about a missing subdirectory in `extern`, then either: diff --git a/extern/imgui_patched/imconfig_fur.h b/extern/imgui_patched/imconfig_fur.h index 13622fab7..09ceebd2d 100644 --- a/extern/imgui_patched/imconfig_fur.h +++ b/extern/imgui_patched/imconfig_fur.h @@ -74,9 +74,9 @@ //---- Use FreeType to build and rasterize the font atlas (instead of stb_truetype which is embedded by default in Dear ImGui) // Requires FreeType headers to be available in the include path. Requires program to be compiled with 'misc/freetype/imgui_freetype.cpp' (in this repository) + the FreeType library (not provided). // On Windows you may use vcpkg with 'vcpkg install freetype --triplet=x64-windows' + 'vcpkg integrate install'. -#ifdef HAVE_FREETYPE -#define IMGUI_ENABLE_FREETYPE -#endif +//#ifdef HAVE_FREETYPE +//#define IMGUI_ENABLE_FREETYPE +//#endif //---- Use stb_truetype to build and rasterize the font atlas (default) // The only purpose of this define is if you want force compilation of the stb_truetype backend ALONG with the FreeType backend. diff --git a/src/gui/gui.h b/src/gui/gui.h index e7e5d1177..267cb3297 100644 --- a/src/gui/gui.h +++ b/src/gui/gui.h @@ -1602,6 +1602,11 @@ class FurnaceGUI { int showPool; int writeInsNames; int readInsNames; + int fontBackend; + int fontHinting; + int fontBitmap; + int fontAutoHint; + int fontAntiAlias; unsigned int maxUndoSteps; String mainFontPath; String headFontPath; @@ -1786,6 +1791,11 @@ class FurnaceGUI { showPool(0), writeInsNames(1), readInsNames(1), + fontBackend(0), + fontHinting(0), + fontBitmap(0), + fontAutoHint(1), + fontAntiAlias(1), maxUndoSteps(100), mainFontPath(""), headFontPath(""), diff --git a/src/gui/settings.cpp b/src/gui/settings.cpp index 011226bbb..ab0ef749c 100644 --- a/src/gui/settings.cpp +++ b/src/gui/settings.cpp @@ -18,6 +18,7 @@ */ #include "gui.h" +#include "imgui_internal.h" #include "fonts.h" #include "../ta-log.h" #include "../fileutils.h" @@ -29,9 +30,9 @@ #include "IconsFontAwesome4.h" #include "furIcons.h" #include "misc/cpp/imgui_stdlib.h" +#include "misc/freetype/imgui_freetype.h" #include "scaling.h" #include -#include #define DEFAULT_NOTE_KEYS "5:7;6:4;7:3;8:16;10:6;11:8;12:24;13:10;16:11;17:9;18:26;19:28;20:12;21:17;22:1;23:19;24:23;25:5;26:14;27:2;28:21;29:0;30:100;31:13;32:15;34:18;35:20;36:22;38:25;39:27;43:100;46:101;47:29;48:31;53:102;" @@ -50,6 +51,11 @@ #define SYS_FILE_DIALOG_DEFAULT 1 #endif +const char* fontBackends[]={ + "stb_truetype", + "FreeType" +}; + const char* mainFonts[]={ "IBM Plex Sans", "Liberation Sans", @@ -2340,6 +2346,17 @@ void FurnaceGUI::drawSettings() { if (ImGui::BeginTable("##Text",2)) { ImGui::TableSetupColumn("##Label",ImGuiTableColumnFlags_WidthFixed); ImGui::TableSetupColumn("##Combos",ImGuiTableColumnFlags_WidthStretch); +#ifdef HAVE_FREETYPE + ImGui::TableNextRow(); + ImGui::TableNextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text("Font renderer"); + ImGui::TableNextColumn(); + if (ImGui::Combo("##FontBack",&settings.fontBackend,fontBackends,2)) settingsChanged=true; +#else + settings.fontBackend=0; +#endif + ImGui::TableNextRow(); ImGui::TableNextColumn(); ImGui::AlignTextToFramePadding(); @@ -2400,6 +2417,56 @@ void FurnaceGUI::drawSettings() { ImGui::EndTable(); } + if (settings.fontBackend==1) { + bool fontAntiAliasB=settings.fontAntiAlias; + if (ImGui::Checkbox("Anti-aliased fonts",&fontAntiAliasB)) { + settings.fontAntiAlias=fontAntiAliasB; + settingsChanged=true; + } + + bool fontBitmapB=settings.fontBitmap; + if (ImGui::Checkbox("Support bitmap fonts",&fontBitmapB)) { + settings.fontBitmap=fontBitmapB; + settingsChanged=true; + } + + ImGui::Text("Hinting:"); + ImGui::Indent(); + if (ImGui::RadioButton("Off (soft)##fh0",settings.fontHinting==0)) { + settings.fontHinting=0; + settingsChanged=true; + } + if (ImGui::RadioButton("Slight##fh1",settings.fontHinting==1)) { + settings.fontHinting=1; + settingsChanged=true; + } + if (ImGui::RadioButton("Normal##fh2",settings.fontHinting==2)) { + settings.fontHinting=2; + settingsChanged=true; + } + if (ImGui::RadioButton("Full (hard)##fh3",settings.fontHinting==3)) { + settings.fontHinting=3; + settingsChanged=true; + } + ImGui::Unindent(); + + ImGui::Text("Auto-hinter:"); + ImGui::Indent(); + if (ImGui::RadioButton("Disable##fah0",settings.fontAutoHint==0)) { + settings.fontAutoHint=0; + settingsChanged=true; + } + if (ImGui::RadioButton("Enable##fah1",settings.fontAutoHint==1)) { + settings.fontAutoHint=1; + settingsChanged=true; + } + if (ImGui::RadioButton("Force##fah2",settings.fontAutoHint==2)) { + settings.fontAutoHint=2; + settingsChanged=true; + } + ImGui::Unindent(); + } + bool loadJapaneseB=settings.loadJapanese; if (ImGui::Checkbox("Display Japanese characters",&loadJapaneseB)) { settings.loadJapanese=loadJapaneseB; @@ -3650,6 +3717,11 @@ void FurnaceGUI::syncSettings() { settings.writeInsNames=e->getConfInt("writeInsNames",1); settings.readInsNames=e->getConfInt("readInsNames",1); settings.defaultAuthorName=e->getConfString("defaultAuthorName",""); + settings.fontBackend=e->getConfInt("fontBackend",0); + settings.fontHinting=e->getConfInt("fontHinting",0); + settings.fontBitmap=e->getConfInt("fontBitmap",0); + settings.fontAutoHint=e->getConfInt("fontAutoHint",1); + settings.fontAntiAlias=e->getConfInt("fontAntiAlias",1); clampSetting(settings.mainFontSize,2,96); clampSetting(settings.headFontSize,2,96); @@ -3805,6 +3877,11 @@ void FurnaceGUI::syncSettings() { clampSetting(settings.showPool,0,1); clampSetting(settings.writeInsNames,0,1); clampSetting(settings.readInsNames,0,1); + clampSetting(settings.fontBackend,0,1); + clampSetting(settings.fontHinting,0,3); + clampSetting(settings.fontBitmap,0,1); + clampSetting(settings.fontAutoHint,0,2); + clampSetting(settings.fontAntiAlias,0,1); if (settings.exportLoops<0.0) settings.exportLoops=0.0; if (settings.exportFadeOut<0.0) settings.exportFadeOut=0.0; @@ -4069,6 +4146,11 @@ void FurnaceGUI::commitSettings() { e->setConf("writeInsNames",settings.writeInsNames); e->setConf("readInsNames",settings.readInsNames); e->setConf("defaultAuthorName",settings.defaultAuthorName); + e->setConf("fontBackend",settings.fontBackend); + e->setConf("fontHinting",settings.fontHinting); + e->setConf("fontBitmap",settings.fontBitmap); + e->setConf("fontAutoHint",settings.fontAutoHint); + e->setConf("fontAntiAlias",settings.fontAntiAlias); // colors for (int i=0; iFontBuilderIO=ImGuiFreeType::GetBuilderForFreeType(); + ImGui::GetIO().Fonts->FontBuilderFlags&=~( + ImGuiFreeTypeBuilderFlags_NoHinting| + ImGuiFreeTypeBuilderFlags_NoAutoHint| + ImGuiFreeTypeBuilderFlags_ForceAutoHint| + ImGuiFreeTypeBuilderFlags_LightHinting| + ImGuiFreeTypeBuilderFlags_MonoHinting| + ImGuiFreeTypeBuilderFlags_Bold| + ImGuiFreeTypeBuilderFlags_Oblique| + ImGuiFreeTypeBuilderFlags_Monochrome| + ImGuiFreeTypeBuilderFlags_LoadColor| + ImGuiFreeTypeBuilderFlags_Bitmap + ); + + if (!settings.fontAntiAlias) ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_Monochrome; + if (settings.fontBitmap) ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_Bitmap; + + switch (settings.fontHinting) { + case 0: // off + ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_NoHinting; + break; + case 1: // slight + ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_LightHinting; + break; + case 2: // normal + break; + case 3: // full + ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_MonoHinting; + break; + } + + switch (settings.fontAutoHint) { + case 0: // off + ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_NoAutoHint; + break; + case 1: // on + break; + case 2: // force + ImGui::GetIO().Fonts->FontBuilderFlags|=ImGuiFreeTypeBuilderFlags_ForceAutoHint; + break; + } + } else { + ImGui::GetIO().Fonts->FontBuilderIO=ImFontAtlasGetBuilderForStbTruetype(); + } +#endif + + // set to 800 for now due to problems with unifont static const ImWchar upTo800[]={0x20,0x7e,0xa0,0x800,0}; ImFontGlyphRangesBuilder range;