Move fontconfig-related code out to a class.
authorCarl Hetherington <cth@carlh.net>
Thu, 2 Jun 2022 10:52:59 +0000 (12:52 +0200)
committerCarl Hetherington <cth@carlh.net>
Tue, 7 Jun 2022 15:01:06 +0000 (17:01 +0200)
src/lib/font_config.cc [new file with mode: 0644]
src/lib/font_config.h [new file with mode: 0644]
src/lib/render_text.cc
src/lib/wscript

diff --git a/src/lib/font_config.cc b/src/lib/font_config.cc
new file mode 100644 (file)
index 0000000..c7361bc
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+    Copyright (C) 2014-2021 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"
+#include "font_config.h"
+#include <fontconfig/fontconfig.h>
+#include <boost/optional.hpp>
+
+
+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<string> font_name;
+       FcConfigAppFontAddFile (_config, reinterpret_cast<FcChar8 const *>(font_file.string().c_str()));
+       auto pattern = FcPatternBuild (
+               0, FC_FILE, FcTypeString, font_file.string().c_str(), static_cast<char *>(0)
+               );
+       auto object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, static_cast<char *> (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<char const *> (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 (file)
index 0000000..7527d91
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+    Copyright (C) 2014-2021 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 <fontconfig/fontconfig.h>
+#include <boost/filesystem.hpp>
+#include <map>
+#include <string>
+
+
+/** 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<boost::filesystem::path, std::string> _available_fonts;
+
+       static FontConfig* _instance;
+};
+
index e0eb3da7b9f22af7e0eb7fdfe8fd9100246000a5..f1fce62b07dbac20c47a0169967634379ffe1b70 100644 (file)
 #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 <dcp/raw_convert.h>
 #include <dcp/warnings.h>
-#include <fontconfig/fontconfig.h>
 #include <cairomm/cairomm.h>
 LIBDCP_DISABLE_WARNINGS
 #include <pangomm.h>
@@ -51,10 +51,6 @@ using std::string;
 using namespace dcpomatic;
 
 
-static FcConfig* fc_config = nullptr;
-static list<pair<boost::filesystem::path, string>> 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> image)
 static string
 setup_font (StringText const& subtitle, list<shared_ptr<Font>> 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<shared_ptr<Font>> 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<FcChar8 const *>(font_file.string().c_str()));
-               auto pattern = FcPatternBuild (
-                       0, FC_FILE, FcTypeString, font_file.string().c_str(), static_cast<char *>(0)
-                       );
-               auto object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, static_cast<char *> (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<char const *> (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);
 }
 
 
index f4e478219611a2553c075c15b333a89fa3df1e6f..285ebfab55f045902ae068990314c4493b8534b7 100644 (file)
@@ -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