From 9a7b67aee32a40539f29bc2d7017edd4a4f65f11 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Thu, 2 Jun 2022 12:52:59 +0200 Subject: [PATCH] Move fontconfig-related code out to a class. --- src/lib/font_config.cc | 97 ++++++++++++++++++++++++++++++++++++++++++ src/lib/font_config.h | 44 +++++++++++++++++++ src/lib/render_text.cc | 53 +---------------------- src/lib/wscript | 1 + 4 files changed, 144 insertions(+), 51 deletions(-) create mode 100644 src/lib/font_config.cc create mode 100644 src/lib/font_config.h diff --git a/src/lib/font_config.cc b/src/lib/font_config.cc new file mode 100644 index 000000000..c7361bc04 --- /dev/null +++ b/src/lib/font_config.cc @@ -0,0 +1,97 @@ +/* + Copyright (C) 2014-2021 Carl Hetherington + + 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 . + +*/ + + +#include "dcpomatic_assert.h" +#include "font_config.h" +#include +#include + + +using std::string; +using boost::optional; + + +FontConfig* FontConfig::_instance; + + +FontConfig::FontConfig() +{ + _config = FcInitLoadConfigAndFonts(); + FcConfigSetCurrent(_config); +} + + +string +FontConfig::make_font_available(boost::filesystem::path font_file) +{ + auto existing = _available_fonts.find(font_file); + if (existing != _available_fonts.end()) { + return existing->second; + } + + /* Make this font available to DCP-o-matic */ + optional font_name; + FcConfigAppFontAddFile (_config, reinterpret_cast(font_file.string().c_str())); + auto pattern = FcPatternBuild ( + 0, FC_FILE, FcTypeString, font_file.string().c_str(), static_cast(0) + ); + auto object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, static_cast (0)); + auto font_set = FcFontList (_config, pattern, object_set); + if (font_set) { + for (int i = 0; i < font_set->nfont; ++i) { + FcPattern* font = font_set->fonts[i]; + FcChar8* file; + FcChar8* family; + FcChar8* style; + if ( + FcPatternGetString (font, FC_FILE, 0, &file) == FcResultMatch && + FcPatternGetString (font, FC_FAMILY, 0, &family) == FcResultMatch && + FcPatternGetString (font, FC_STYLE, 0, &style) == FcResultMatch + ) { + font_name = reinterpret_cast (family); + } + } + + FcFontSetDestroy (font_set); + } + + FcObjectSetDestroy (object_set); + FcPatternDestroy (pattern); + + DCPOMATIC_ASSERT(font_name); + + _available_fonts[font_file] = *font_name; + + FcConfigBuildFonts(_config); + return *font_name; +} + + +FontConfig * +FontConfig::instance() +{ + if (!_instance) { + _instance = new FontConfig(); + } + + return _instance; +} + diff --git a/src/lib/font_config.h b/src/lib/font_config.h new file mode 100644 index 000000000..7527d9127 --- /dev/null +++ b/src/lib/font_config.h @@ -0,0 +1,44 @@ +/* + Copyright (C) 2014-2021 Carl Hetherington + + 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 . + +*/ + + +#include +#include +#include +#include + + +/** Wrapper for the fontconfig library */ +class FontConfig +{ +public: + static FontConfig* instance(); + + std::string make_font_available(boost::filesystem::path font_file); + +private: + FontConfig(); + + FcConfig* _config = nullptr; + std::map _available_fonts; + + static FontConfig* _instance; +}; + diff --git a/src/lib/render_text.cc b/src/lib/render_text.cc index e0eb3da7b..f1fce62b0 100644 --- a/src/lib/render_text.cc +++ b/src/lib/render_text.cc @@ -22,13 +22,13 @@ #include "cross.h" #include "dcpomatic_assert.h" #include "font.h" +#include "font_config.h" #include "image.h" #include "render_text.h" #include "types.h" #include "util.h" #include #include -#include #include LIBDCP_DISABLE_WARNINGS #include @@ -51,10 +51,6 @@ using std::string; using namespace dcpomatic; -static FcConfig* fc_config = nullptr; -static list> fc_config_fonts; - - /** Create a Pango layout using a dummy context which we can use to calculate the size * of the text we will render. Then we can transfer the layout over to the real context * for the actual render. @@ -177,10 +173,6 @@ create_surface (shared_ptr image) static string setup_font (StringText const& subtitle, list> const& fonts) { - if (!fc_config) { - fc_config = FcInitLoadConfig (); - } - auto font_file = default_font_file (); for (auto i: fonts) { @@ -189,48 +181,7 @@ setup_font (StringText const& subtitle, list> const& fonts) } } - auto existing = fc_config_fonts.cbegin (); - while (existing != fc_config_fonts.end() && existing->first != font_file) { - ++existing; - } - - string font_name; - if (existing != fc_config_fonts.end ()) { - font_name = existing->second; - } else { - /* Make this font available to DCP-o-matic */ - FcConfigAppFontAddFile (fc_config, reinterpret_cast(font_file.string().c_str())); - auto pattern = FcPatternBuild ( - 0, FC_FILE, FcTypeString, font_file.string().c_str(), static_cast(0) - ); - auto object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, static_cast (0)); - auto font_set = FcFontList (fc_config, pattern, object_set); - if (font_set) { - for (int i = 0; i < font_set->nfont; ++i) { - FcPattern* font = font_set->fonts[i]; - FcChar8* file; - FcChar8* family; - FcChar8* style; - if ( - FcPatternGetString (font, FC_FILE, 0, &file) == FcResultMatch && - FcPatternGetString (font, FC_FAMILY, 0, &family) == FcResultMatch && - FcPatternGetString (font, FC_STYLE, 0, &style) == FcResultMatch - ) { - font_name = reinterpret_cast (family); - } - } - - FcFontSetDestroy (font_set); - } - - FcObjectSetDestroy (object_set); - FcPatternDestroy (pattern); - - fc_config_fonts.push_back (make_pair(font_file, font_name)); - } - - FcConfigSetCurrent (fc_config); - return font_name; + return FontConfig::instance()->make_font_available(font_file); } diff --git a/src/lib/wscript b/src/lib/wscript index f4e478219..285ebfab5 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -115,6 +115,7 @@ sources = """ filter.cc font.cc font_data.cc + font_config.cc frame_interval_checker.cc frame_rate_change.cc guess_crop.cc -- 2.30.2