Skip to content

Commit af985e1

Browse files
peterhorvath111lgritz
authored andcommitted
Update font enumeration (#4508)
Fixes #4504 The PR removes the code that looks for font folders based on a prefix and suffix list. Instead, adds all known system font folders per each platform. The global "font_searchpath" attribute, `OPENIMAGEIO_FONTS` and `OpenImageIO_ROOT` environment variables are still searched as before, such as fonts directories relative to the currently running binary. However $HOME and $SystemRoot folders (with all previous suffixes) are not searched anymore, thus this is a breaking change, and the documentation might need to be updated accordingly. The search order did not change. It's still "font_searchpath" attribute, environment variables, system font folders, folders relative to binary. --------- Signed-off-by: peter.horvath <peter.horvath@autodesk.com>
1 parent 735bba9 commit af985e1

1 file changed

Lines changed: 48 additions & 19 deletions

File tree

src/libOpenImageIO/imagebufalgo_draw.cpp

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <limits>
88
#include <set>
99
#include <unordered_map>
10+
#include <unordered_set>
1011

1112
#include <OpenImageIO/half.h>
1213

@@ -732,13 +733,9 @@ static std::vector<std::string> all_font_files;
732733
static std::vector<std::string> all_fonts;
733734
static std::unordered_map<std::string, std::string> font_file_map;
734735
static std::mutex font_search_mutex;
735-
static bool fonts_are_enumerated = false;
736-
static const char* font_dir_prefix_envvars[]
737-
= { "OPENIMAGEIO_FONTS", "HOME", "SystemRoot", "OpenImageIO_ROOT" };
738-
static const char* font_dir_prefixes[]
739-
= { "/Library/Fonts", "/System/Library/Fonts",
740-
"C:/Windows", "/usr",
741-
"/usr/local", "/opt/local" };
736+
static bool fonts_are_enumerated = false;
737+
static const char* font_dir_envvars[] = { "OPENIMAGEIO_FONTS",
738+
"OpenImageIO_ROOT" };
742739
static const char* font_dir_suffixes[]
743740
= { "fonts", "Fonts", "Library/Fonts",
744741
"share/fonts", "share/Fonts", "share/fonts/OpenImageIO" };
@@ -799,31 +796,63 @@ enumerate_fonts()
799796
// Find all the existing dirs from the font search path to populate
800797
// font_search_dirs.
801798
fontpath_add_from_searchpath(pvt::font_searchpath);
802-
for (auto s : font_dir_prefix_envvars)
799+
// Find all the existing dirs from specific environment variables.
800+
for (auto s : font_dir_envvars)
803801
fontpath_add_from_searchpath(Sysutil::getenv(s));
804-
for (auto s : font_dir_prefixes)
805-
fontpath_add_from_dir(s);
802+
803+
// Add system font directories
804+
#ifdef _WIN32
805+
fontpath_add_one_dir(std::string(Sysutil::getenv("SystemRoot")) + "/Fonts");
806+
fontpath_add_one_dir(std::string(Sysutil::getenv("LOCALAPPDATA"))
807+
+ "/Microsoft/Windows/Fonts");
808+
#endif
809+
#ifdef __APPLE__
810+
fontpath_add_one_dir("/Library/Fonts");
811+
fontpath_add_one_dir("/System/Library/Fonts");
812+
fontpath_add_one_dir("/System/Library/Fonts/Supplemental");
813+
fontpath_add_one_dir(std::string(Sysutil::getenv("HOME"))
814+
+ "/Library/Fonts");
815+
#endif
816+
#ifdef __linux__
817+
fontpath_add_one_dir("/usr/share/fonts", 1);
818+
fontpath_add_one_dir("/usr/local/share/fonts", 1);
819+
fontpath_add_one_dir(std::string(Sysutil::getenv("HOME")) + "/.fonts", 1);
820+
fontpath_add_one_dir(std::string(Sysutil::getenv("HOME"))
821+
+ "/.local/share/fonts",
822+
1);
823+
#endif
824+
// Find font directories one level up from the place
825+
// where the currently running binary lives.
806826
std::string this_program = OIIO::Sysutil::this_program_path();
807827
if (this_program.size()) {
808828
std::string path = Filesystem::parent_path(this_program);
809829
path = Filesystem::parent_path(path);
810830
fontpath_add_from_dir(path);
811831
}
812832

813-
// Get list of directories one level deeper than the font_search_dirs
814-
auto dirs = font_search_dirs;
815-
for (auto& dir : font_search_dirs) {
816-
std::vector<std::string> filenames;
817-
Filesystem::get_directory_entries(dir, filenames, false);
818-
for (auto& f : filenames)
819-
if (f.size() && Filesystem::is_directory(f))
820-
dirs.push_back(f);
833+
// Make sure folders are not duplicated
834+
std::vector<std::string> tmp_font_search_dirs = font_search_dirs;
835+
font_search_dirs.clear();
836+
std::unordered_set<std::string> font_search_dir_set;
837+
for (const std::string& dir : tmp_font_search_dirs) {
838+
std::string target_dir = dir;
839+
#ifdef _WIN32
840+
// Windows is not case-sensitive, compare lower case paths
841+
target_dir = Strutil::lower(target_dir);
842+
// unify path separators
843+
target_dir = Strutil::replace(target_dir, "/", "\\", true);
844+
#endif
845+
if (font_search_dir_set.find(target_dir) != font_search_dir_set.end())
846+
continue;
847+
848+
font_search_dirs.push_back(dir);
849+
font_search_dir_set.insert(target_dir);
821850
}
822851

823852
// Look for all the font files in dirs, populate font_file_set and font_set
824853
std::set<std::string> font_set;
825854
std::set<std::string> font_file_set;
826-
for (auto& dir : dirs) {
855+
for (auto& dir : font_search_dirs) {
827856
std::vector<std::string> filenames;
828857
Filesystem::get_directory_entries(dir, filenames, false);
829858
for (auto& f : filenames) {

0 commit comments

Comments
 (0)