Only index the first kilobyte of font files to speed up indexing

This commit is contained in:
Thomas Goyne 2015-12-25 12:27:41 -08:00
parent 82f250dbbb
commit 879661a379
2 changed files with 26 additions and 16 deletions

View file

@ -42,7 +42,7 @@ struct CollectionResult {
#ifdef _WIN32
class GdiFontFileLister {
std::unordered_map<std::string, agi::fs::path> index;
std::unordered_multimap<std::string, agi::fs::path> index;
agi::scoped_holder<HDC> dc;
std::string buffer;

View file

@ -57,23 +57,18 @@ std::vector<agi::fs::path> get_installed_fonts() {
return files;
}
std::string read_file(agi::fs::path const& path) {
std::string data;
auto stream = agi::io::Open(path, true);
stream->seekg(0, std::ios::end);
data.resize(stream->tellg());
stream->seekg(0, std::ios::beg);
stream->read(&data[0], data.size());
return data;
}
using font_index = std::unordered_map<std::string, agi::fs::path>;
using font_index = std::unordered_multimap<std::string, agi::fs::path>;
font_index index_fonts() {
font_index hash_to_path;
auto fonts = get_installed_fonts();
for (auto const& path : fonts) {
hash_to_path[read_file(path)] = path;
auto stream = agi::io::Open(path, true);
std::string data(1024, '\0');
stream->read(&data[0], data.size());
data.resize(stream->tellg());
hash_to_path.emplace(std::move(data), path);
}
return hash_to_path;
}
@ -163,11 +158,26 @@ CollectionResult GdiFontFileLister::GetFontPaths(std::string const& facename, in
get_font_data(buffer, dc);
auto it = index.find(buffer);
if (it == end(index))
auto range = index.equal_range(buffer.substr(0, 1024));
if (range.first == range.second)
return ret; // could instead write to a temp dir
ret.paths.push_back(it->second);
// Compare the full files for each of the fonts with the same prefix
std::unique_ptr<char[]> file_buffer(new char[buffer.size()]);
for (auto it = range.first; it != range.second; ++it) {
auto stream = agi::io::Open(it->second, true);
stream->read(&file_buffer[0], buffer.size());
if ((size_t)stream->tellg() != buffer.size())
continue;
if (memcmp(&file_buffer[0], &buffer[0], buffer.size()) == 0) {
ret.paths.push_back(it->second);
break;
}
}
// No fonts actually matched
if (ret.paths.empty())
return ret;
// Convert the characters to a utf-16 string
std::wstring utf16characters;