Added more options to font loading.
This commit is contained in:
parent
830fdd434b
commit
1d75400a2d
2
SModule
2
SModule
@ -4,7 +4,7 @@ Import('env')
|
||||
public_dir = env.Dir('public')
|
||||
env.Append(CPPPATH = [public_dir])
|
||||
if env['BUILD_TYPE'] == 'release':
|
||||
cppdefines += ['RAID_RELEASE=1']
|
||||
env.Append(CPPDEFINES = ['RAID_RELEASE'])
|
||||
env = env.Module('private/raid/SModule')
|
||||
|
||||
LIB_CONFIG = {
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include <SDL3/SDL.h>
|
||||
#include <mijin/debug/assert.hpp>
|
||||
#include <mijin/platform/folders.hpp>
|
||||
#include <mijin/util/iterators.hpp>
|
||||
#include <mijin/util/scope_guard.hpp>
|
||||
#include <mijin/virtual_filesystem/mapping.hpp>
|
||||
#include <mijin/virtual_filesystem/relative.hpp>
|
||||
@ -125,29 +126,55 @@ int Application::run(int argc, char** argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Application::loadFont(const fs::path& path)
|
||||
|
||||
bool Application::loadFonts(std::span<const FontConfig> fonts)
|
||||
{
|
||||
ImGuiIO& imguiIO = ImGui::GetIO();
|
||||
|
||||
std::vector<mijin::TypelessBuffer> buffers;
|
||||
buffers.reserve(fonts.size());
|
||||
|
||||
for (const FontConfig& font : fonts)
|
||||
{
|
||||
std::unique_ptr<mijin::Stream> fontFile;
|
||||
if (const mijin::StreamError error = mFS.open(path, mijin::FileOpenMode::READ, fontFile);
|
||||
if (const mijin::StreamError error = mFS.open(font.path, mijin::FileOpenMode::READ, fontFile);
|
||||
error != mijin::StreamError::SUCCESS)
|
||||
{
|
||||
msgError("Error opening font file {}: {}.", path.generic_string(), mijin::errorName(error));
|
||||
msgError("Error opening font file {}: {}.", font.path.generic_string(), mijin::errorName(error));
|
||||
return false;
|
||||
}
|
||||
|
||||
mijin::TypelessBuffer data;
|
||||
mijin::TypelessBuffer& data = buffers.emplace_back();
|
||||
if (const mijin::StreamError readError = fontFile->readRest(data); readError != mijin::StreamError::SUCCESS)
|
||||
{
|
||||
msgError("Error reading font data from {}: {}.", path.generic_string(), mijin::errorName(readError));
|
||||
msgError("Error reading font data from {}: {}.", font.path.generic_string(), mijin::errorName(readError));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// by default ImGui takes ownership of the data, that's now what we want
|
||||
ImFontConfig config;
|
||||
config.FontDataOwnedByAtlas = false;
|
||||
imguiIO.Fonts->AddFontFromMemoryTTF(data.data(), static_cast<int>(data.byteSize()), 20, &config);
|
||||
std::vector<ImWchar> glyphRangesConverted;
|
||||
for (const auto& [font, data] : mijin::zip(fonts, buffers))
|
||||
{
|
||||
ImWchar* glyphRanges = nullptr;
|
||||
if (!font.glyphRanges.empty())
|
||||
{
|
||||
glyphRangesConverted.reserve(2 * font.glyphRanges.size() + 1);
|
||||
glyphRangesConverted.clear();
|
||||
for (const std::pair<ImWchar, ImWchar>& range : font.glyphRanges)
|
||||
{
|
||||
glyphRangesConverted.push_back(range.first);
|
||||
glyphRangesConverted.push_back(range.second);
|
||||
}
|
||||
glyphRangesConverted.push_back(0);
|
||||
glyphRanges = glyphRangesConverted.data();
|
||||
}
|
||||
config.PixelSnapH = font.flags.pixelSnapH;
|
||||
imguiIO.Fonts->AddFontFromMemoryTTF(data.data(), static_cast<int>(data.byteSize()), font.size, &config, glyphRanges);
|
||||
config.MergeMode = true; // for any more fonts
|
||||
}
|
||||
|
||||
// but in that case Build() has to be run before the data gets deleted
|
||||
imguiIO.Fonts->Build();
|
||||
@ -209,6 +236,13 @@ void Application::configureImgui()
|
||||
imguiIO.ConfigViewportsNoAutoMerge = true;
|
||||
}
|
||||
|
||||
std::vector<FontConfig> Application::getDefaultFonts()
|
||||
{
|
||||
return {{
|
||||
.path = "/data/fonts/NotoSans-Regular.ttf"
|
||||
}};
|
||||
}
|
||||
|
||||
void Application::handleMessage(const Message& message)
|
||||
{
|
||||
switch (message.severity)
|
||||
@ -452,8 +486,7 @@ bool Application::initImGui()
|
||||
// init font
|
||||
if (imguiIO.Fonts->Fonts.empty())
|
||||
{
|
||||
static const char* const DEFAULT_FONT = "/data/fonts/NotoSans-Regular.ttf";
|
||||
if (!loadFont(DEFAULT_FONT))
|
||||
if (!loadFonts(getDefaultFonts()))
|
||||
{
|
||||
imguiIO.Fonts->AddFontDefault();
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <fmt/format.h>
|
||||
#include <imgui.h>
|
||||
#include <mijin/async/coroutine.hpp>
|
||||
#include <mijin/util/bitflags.hpp>
|
||||
#include <mijin/virtual_filesystem/stacked.hpp>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
@ -34,6 +35,19 @@ struct Message
|
||||
const char* text;
|
||||
};
|
||||
|
||||
struct FontFlags : mijin::BitFlags<FontFlags>
|
||||
{
|
||||
bool pixelSnapH : 1 = false;
|
||||
};
|
||||
|
||||
struct FontConfig
|
||||
{
|
||||
fs::path path;
|
||||
std::vector<std::pair<ImWchar, ImWchar>> glyphRanges;
|
||||
float size = 20.f;
|
||||
FontFlags flags;
|
||||
};
|
||||
|
||||
class Application
|
||||
{
|
||||
private:
|
||||
@ -90,7 +104,13 @@ public:
|
||||
int run(int argc, char* argv[]);
|
||||
|
||||
[[nodiscard]]
|
||||
bool loadFont(const fs::path& path);
|
||||
bool loadFonts(std::span<const FontConfig> fonts);
|
||||
|
||||
[[nodiscard]]
|
||||
bool loadFont(const FontConfig& font)
|
||||
{
|
||||
return loadFonts({&font, 1});
|
||||
}
|
||||
|
||||
[[nodiscard]]
|
||||
ImTextureID getOrLoadTexture(fs::path path);
|
||||
@ -100,6 +120,7 @@ protected:
|
||||
virtual std::string getFolderName() = 0;
|
||||
virtual std::string getWindowTitle() = 0;
|
||||
virtual void configureImgui();
|
||||
virtual std::vector<FontConfig> getDefaultFonts();
|
||||
virtual void handleMessage(const Message& message);
|
||||
virtual void handleSDLEvent(const SDL_Event& event);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user