diff options
| -rw-r--r-- | src/lib/font.h | 4 | ||||
| -rw-r--r-- | src/lib/font_comparator.h | 68 | ||||
| -rw-r--r-- | src/lib/font_config.cc | 7 | ||||
| -rw-r--r-- | src/lib/font_config.h | 3 | ||||
| -rw-r--r-- | test/font_comparator_test.cc | 27 | ||||
| -rw-r--r-- | test/wscript | 1 |
6 files changed, 107 insertions, 3 deletions
diff --git a/src/lib/font.h b/src/lib/font.h index b9e90f65e..0afd873e1 100644 --- a/src/lib/font.h +++ b/src/lib/font.h @@ -85,6 +85,10 @@ public: boost::optional<boost::filesystem::path> file; }; + Content content() const { + return _content; + } + boost::signals2::signal<void()> Changed; private: 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; + }; +}; + + diff --git a/src/lib/font_config.cc b/src/lib/font_config.cc index d4a442fc1..8804bd6d9 100644 --- a/src/lib/font_config.cc +++ b/src/lib/font_config.cc @@ -56,7 +56,7 @@ FontConfig::~FontConfig() string FontConfig::make_font_available(shared_ptr<dcpomatic::Font> font) { - auto existing = _available_fonts.find(font->id()); + auto existing = _available_fonts.find(font->content()); if (existing != _available_fonts.end()) { return existing->second; } @@ -107,7 +107,10 @@ FontConfig::make_font_available(shared_ptr<dcpomatic::Font> font) DCPOMATIC_ASSERT(font_name); - _available_fonts[font->id()] = *font_name; + /* We need to use the font object as the key, as we may be passed the same shared_ptr to a modified + * Font object in the future and in that case we need to load the new font. + */ + _available_fonts[font->content()] = *font_name; FcConfigBuildFonts(_config); return *font_name; diff --git a/src/lib/font_config.h b/src/lib/font_config.h index edcb4be36..57f733b7b 100644 --- a/src/lib/font_config.h +++ b/src/lib/font_config.h @@ -19,6 +19,7 @@ */ +#include "font_comparator.h" #include <fontconfig/fontconfig.h> #include <boost/filesystem.hpp> #include <map> @@ -41,7 +42,7 @@ private: ~FontConfig(); FcConfig* _config = nullptr; - std::map<std::string, std::string> _available_fonts; + std::map<dcpomatic::Font::Content, std::string, FontComparator> _available_fonts; std::vector<boost::filesystem::path> _temp_files; diff --git a/test/font_comparator_test.cc b/test/font_comparator_test.cc new file mode 100644 index 000000000..dad058a74 --- /dev/null +++ b/test/font_comparator_test.cc @@ -0,0 +1,27 @@ +#include "lib/font.h" +#include "lib/font_comparator.h" +#include <boost/test/unit_test.hpp> +#include <iostream> + + +using std::make_shared; +using std::map; +using std::shared_ptr; +using std::string; + + +BOOST_AUTO_TEST_CASE(font_comparator_test) +{ + map<dcpomatic::Font::Content, string, FontComparator> cache; + + auto font = make_shared<dcpomatic::Font>("foo"); + + BOOST_CHECK(cache.find(font->content()) == cache.end()); + cache[font->content()] = "foo"; + BOOST_CHECK(cache.find(font->content()) != cache.end()); + + font->set_file("test/data/Inconsolata-VF.ttf"); + BOOST_CHECK(cache.find(font->content()) == cache.end()); +} + + diff --git a/test/wscript b/test/wscript index 9917e7802..827a3feb8 100644 --- a/test/wscript +++ b/test/wscript @@ -94,6 +94,7 @@ def build(bld): file_naming_test.cc film_metadata_test.cc find_missing_test.cc + font_comparator_test.cc frame_interval_checker_test.cc frame_rate_test.cc guess_crop_test.cc |
