diff options
| author | Carl Hetherington <cth@carlh.net> | 2023-04-19 23:57:03 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2023-04-19 23:57:03 +0200 |
| commit | 22aa0dd620b6db93a64e1e171fb5ddb18693e56e (patch) | |
| tree | eff4188e9877983f666b8c53b767d68d4a2ad212 /src/lib/font_comparator.h | |
| parent | f6a51c4902d6c1983d58e1073f048d50ba2a50df (diff) | |
In 1c73379ed8483dcf71c5ccfc459c2c22516a9aef I changed
FontConfig::_available_fonts to use the font ID as a key, but that's
totally wrong because the same Font object with the same ID can have
its font filename/data changed, and in that case we don't want to
use the cached font.
Here we use the actual TTF/OTF font data as the key. We could have
just hashed the data (whether it comes from a disk file or is held
in memory) but this is slower in the case where we have the filename,
as then the file must be loaded from disk for each comparison.
This fixes #2518.
Diffstat (limited to 'src/lib/font_comparator.h')
| -rw-r--r-- | src/lib/font_comparator.h | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/lib/font_comparator.h b/src/lib/font_comparator.h new file mode 100644 index 000000000..07ad15b6a --- /dev/null +++ b/src/lib/font_comparator.h @@ -0,0 +1,68 @@ +/* + Copyright (C) 2023 Carl Hetherington <cth@carlh.net> + + This file is part of DCP-o-matic. + + DCP-o-matic is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + DCP-o-matic is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with DCP-o-matic. If not, see <http://www.gnu.org/licenses/>. + +*/ + + +#include "dcpomatic_assert.h" + + +/** Comparator to allow dcpomatic::Font::Content to be compared for use in a map */ +struct FontComparator +{ + bool operator()(dcpomatic::Font::Content const& a, dcpomatic::Font::Content const& b) const { + auto const a_has_file = static_cast<bool>(a.file); + auto const b_has_file = static_cast<bool>(b.file); + auto const a_has_data = static_cast<bool>(a.data); + auto const b_has_data = static_cast<bool>(b.data); + + if (!a_has_file && !a_has_data && !b_has_file && !b_has_data) { + /* Neither font has any font data: a == b */ + return false; + } else if (!a_has_file && !a_has_data) { + /* Fonts with no data are the "lowest": a < b */ + return true; + } else if (!b_has_file && !b_has_data) { + /* ... so here b < a */ + return false; + } else if (a_has_file && !b_has_file) { + /* Fonts with file are lower than fonts with data: a < b */ + return true; + } else if (!a_has_file && b_has_file) { + /* ... so here b < a */ + return false; + } else if (a_has_file && b_has_file) { + /* Compared as "equals" */ + return a.file->string() < b.file->string(); + } else if (a_has_data && b_has_data) { + /* Compared as "equals" */ + auto const a_size = a.data->size(); + auto const b_size = b.data->size(); + if (a_size != b_size) { + return a_size < b_size; + } + return memcmp(a.data->data(), b.data->data(), a_size) < 0; + } + + /* Should never get here */ + DCPOMATIC_ASSERT(false); + return false; + }; +}; + + |
