From 8d6f9d960fbc3546a10741d38e4e90b65cfb71a4 Mon Sep 17 00:00:00 2001 From: dec05eba Date: Thu, 3 Nov 2022 23:13:32 +0100 Subject: Use font config to load custom font path when not using absolute path --- include/Path.hpp | 2 +- src/ResourceLoader.cpp | 106 +++++++++++++++++++++++++------------------------ 2 files changed, 56 insertions(+), 52 deletions(-) diff --git a/include/Path.hpp b/include/Path.hpp index a881a53..3d849e2 100644 --- a/include/Path.hpp +++ b/include/Path.hpp @@ -48,7 +48,7 @@ namespace QuickMedia { return ""; } - Path parent() { + Path parent() const { size_t slash_index = data.rfind('/'); if(slash_index != std::string::npos && slash_index > 0) return Path(data.substr(0, slash_index)); diff --git a/src/ResourceLoader.cpp b/src/ResourceLoader.cpp index 50bb7b5..401ca38 100644 --- a/src/ResourceLoader.cpp +++ b/src/ResourceLoader.cpp @@ -25,9 +25,7 @@ namespace QuickMedia { const char* get_resource_loader_root_path() { return resource_root.c_str(); } -} -namespace QuickMedia::FontLoader { static int accumulate_string(char *data, int size, void *userdata) { std::string *str = (std::string*)userdata; if(str->size() + size > 1024 * 1024 * 100) // 100mb sane limit, TODO: make configurable @@ -36,96 +34,102 @@ namespace QuickMedia::FontLoader { return 0; } + // If absolute, use the path; otherwise use fc-match to find the font + static bool find_font(const std::string &font_name, std::string &font_filepath_result) { + if(get_config().font.latin.find('/') != std::string::npos) { + font_filepath_result = font_name; + return true; + } + + std::string output; + const char *args[] = { "fc-match", font_name.c_str(), "file", nullptr }; + if(exec_program(args, accumulate_string, &output) == 0 && output.size() > 6 && output.size() >= font_name.size()) { + output = strip(output); + if(string_ends_with(output, "/" + font_name)) { + font_filepath_result = output.substr(6); + return true; + } + } + + fprintf(stderr, "Warning: failed to find font: %s\n", font_name.c_str()); + return false; + } +} + +namespace QuickMedia::FontLoader { mgl::Font* get_font(FontType font_type, unsigned int character_size) { // Make mgl font size match sfml font size character_size += 5; mgl::MemoryMappedFile *mapped_file = font_file_cache[(unsigned int)font_type].get(); if(!mapped_file) { - std::vector noto_directories = { - "/usr/share/fonts/noto", - "/usr/share/fonts/truetype/noto", - "/usr/share/fonts/noto-cjk", - "/usr/share/fonts/truetype/noto-cjk", - "/usr/share/fonts/TTF", - }; - + std::vector noto_directories; std::string font_file_name; + std::string found_font_filepath; + std::string output; + switch(font_type) { case FontType::LATIN: { - std::string output; const char *args[] = { "fc-match", "sans:lang=en", "file", nullptr }; if(get_config().use_system_fonts && exec_program(args, accumulate_string, &output) == 0 && output.size() > 6) { Path path = strip(output.substr(6)); noto_directories.push_back(path.parent().data); font_file_name = path.filename(); + } else if(!get_config().font.latin.empty() && find_font(get_config().font.latin, found_font_filepath)) { + const Path font_path = found_font_filepath; + noto_directories.push_back(font_path.parent().data); + font_file_name = font_path.filename(); } else { - Path font_path = get_config().font.latin; - if(font_path.data.empty()) - font_path = "NotoSans-Regular.ttf"; - - if(font_path.data.find('/') == std::string::npos) { - font_file_name = std::move(font_path.data); - } else { - noto_directories.insert(noto_directories.begin(), font_path.parent().data); - font_file_name = font_path.filename(); - } + noto_directories.push_back("/usr/share/fonts/noto"); + noto_directories.push_back("/usr/share/fonts/truetype/noto"); + font_file_name = "NotoSans-Regular.ttf"; } break; } case FontType::LATIN_BOLD: { - std::string output; const char *args[] = { "fc-match", "sans:bold:lang=en", "file", nullptr }; if(get_config().use_system_fonts && exec_program(args, accumulate_string, &output) == 0 && output.size() > 6) { Path path = strip(output.substr(6)); noto_directories.push_back(path.parent().data); font_file_name = path.filename(); + } else if(!get_config().font.latin_bold.empty() && find_font(get_config().font.latin_bold, found_font_filepath)) { + const Path font_path = found_font_filepath; + noto_directories.push_back(font_path.parent().data); + font_file_name = font_path.filename(); } else { - Path font_path = get_config().font.latin_bold; - if(font_path.data.empty()) - font_path = "NotoSans-Bold.ttf"; - - if(font_path.data.find('/') == std::string::npos) { - font_file_name = std::move(font_path.data); - } else { - noto_directories.insert(noto_directories.begin(), font_path.parent().data); - font_file_name = font_path.filename(); - } + noto_directories.push_back("/usr/share/fonts/noto"); + noto_directories.push_back("/usr/share/fonts/truetype/noto"); + font_file_name = "NotoSans-Bold.ttf"; } break; } case FontType::CJK: { - std::string output; const char *args[] = { "fc-match", "sans:lang=ja", "file", nullptr }; if(get_config().use_system_fonts && exec_program(args, accumulate_string, &output) == 0 && output.size() > 6) { Path path = strip(output.substr(6)); noto_directories.push_back(path.parent().data); font_file_name = path.filename(); + } else if(!get_config().font.cjk.empty() && find_font(get_config().font.cjk, found_font_filepath)) { + const Path font_path = found_font_filepath; + noto_directories.push_back(font_path.parent().data); + font_file_name = font_path.filename(); } else { - Path font_path = get_config().font.cjk; - if(font_path.data.empty()) - font_path = "NotoSansCJK-Regular.ttc"; - - if(font_path.data.find('/') == std::string::npos) { - font_file_name = std::move(font_path.data); - } else { - noto_directories.insert(noto_directories.begin(), font_path.parent().data); - font_file_name = font_path.filename(); - } + noto_directories.push_back("/usr/share/fonts/noto-cjk"); + noto_directories.push_back("/usr/share/fonts/truetype/noto-cjk"); + font_file_name = "NotoSansCJK-Regular.ttc"; } break; } case FontType::SYMBOLS: { // TODO: Allow changing with system font setting - Path font_path = get_config().font.symbols; - if(font_path.data.empty()) - font_path = "NotoSansSymbols2-Regular.ttf"; - - if(font_path.data.find('/') == std::string::npos) { - font_file_name = std::move(font_path.data); - } else { - noto_directories.insert(noto_directories.begin(), font_path.parent().data); + if(!get_config().font.symbols.empty() && find_font(get_config().font.symbols, found_font_filepath)) { + const Path font_path = found_font_filepath; + noto_directories.push_back(font_path.parent().data); font_file_name = font_path.filename(); + } else { + noto_directories.push_back("/usr/share/fonts/noto"); + noto_directories.push_back("/usr/share/fonts/truetype/noto"); + font_file_name = "NotoSansSymbols2-Regular.ttf"; } break; } -- cgit v1.2.3