|
7 | 7 | #include <limits> |
8 | 8 | #include <set> |
9 | 9 | #include <unordered_map> |
| 10 | +#include <unordered_set> |
10 | 11 |
|
11 | 12 | #include <OpenImageIO/half.h> |
12 | 13 |
|
@@ -732,13 +733,9 @@ static std::vector<std::string> all_font_files; |
732 | 733 | static std::vector<std::string> all_fonts; |
733 | 734 | static std::unordered_map<std::string, std::string> font_file_map; |
734 | 735 | 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" }; |
742 | 739 | static const char* font_dir_suffixes[] |
743 | 740 | = { "fonts", "Fonts", "Library/Fonts", |
744 | 741 | "share/fonts", "share/Fonts", "share/fonts/OpenImageIO" }; |
@@ -799,31 +796,63 @@ enumerate_fonts() |
799 | 796 | // Find all the existing dirs from the font search path to populate |
800 | 797 | // font_search_dirs. |
801 | 798 | 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) |
803 | 801 | 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. |
806 | 826 | std::string this_program = OIIO::Sysutil::this_program_path(); |
807 | 827 | if (this_program.size()) { |
808 | 828 | std::string path = Filesystem::parent_path(this_program); |
809 | 829 | path = Filesystem::parent_path(path); |
810 | 830 | fontpath_add_from_dir(path); |
811 | 831 | } |
812 | 832 |
|
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); |
821 | 850 | } |
822 | 851 |
|
823 | 852 | // Look for all the font files in dirs, populate font_file_set and font_set |
824 | 853 | std::set<std::string> font_set; |
825 | 854 | std::set<std::string> font_file_set; |
826 | | - for (auto& dir : dirs) { |
| 855 | + for (auto& dir : font_search_dirs) { |
827 | 856 | std::vector<std::string> filenames; |
828 | 857 | Filesystem::get_directory_entries(dir, filenames, false); |
829 | 858 | for (auto& f : filenames) { |
|
0 commit comments