Only index the first kilobyte of font files to speed up indexing
This commit is contained in:
parent
82f250dbbb
commit
879661a379
2 changed files with 26 additions and 16 deletions
|
@ -42,7 +42,7 @@ struct CollectionResult {
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
class GdiFontFileLister {
|
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;
|
agi::scoped_holder<HDC> dc;
|
||||||
std::string buffer;
|
std::string buffer;
|
||||||
|
|
||||||
|
|
|
@ -57,23 +57,18 @@ std::vector<agi::fs::path> get_installed_fonts() {
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string read_file(agi::fs::path const& path) {
|
using font_index = std::unordered_multimap<std::string, agi::fs::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>;
|
|
||||||
|
|
||||||
font_index index_fonts() {
|
font_index index_fonts() {
|
||||||
font_index hash_to_path;
|
font_index hash_to_path;
|
||||||
auto fonts = get_installed_fonts();
|
auto fonts = get_installed_fonts();
|
||||||
for (auto const& path : 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;
|
return hash_to_path;
|
||||||
}
|
}
|
||||||
|
@ -163,11 +158,26 @@ CollectionResult GdiFontFileLister::GetFontPaths(std::string const& facename, in
|
||||||
|
|
||||||
get_font_data(buffer, dc);
|
get_font_data(buffer, dc);
|
||||||
|
|
||||||
auto it = index.find(buffer);
|
auto range = index.equal_range(buffer.substr(0, 1024));
|
||||||
if (it == end(index))
|
if (range.first == range.second)
|
||||||
return ret; // could instead write to a temp dir
|
return ret; // could instead write to a temp dir
|
||||||
|
|
||||||
|
// 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);
|
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
|
// Convert the characters to a utf-16 string
|
||||||
std::wstring utf16characters;
|
std::wstring utf16characters;
|
||||||
|
|
Loading…
Reference in a new issue