Use the correct font to render subtitles in preview / burn-in (#663).
authorCarl Hetherington <cth@carlh.net>
Sun, 23 Aug 2015 17:08:59 +0000 (18:08 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 23 Aug 2015 17:08:59 +0000 (18:08 +0100)
ChangeLog
src/lib/image_subtitle.h
src/lib/player.cc
src/lib/player_subtitles.cc [new file with mode: 0644]
src/lib/player_subtitles.h
src/lib/render_subtitles.cc
src/lib/render_subtitles.h
src/lib/wscript

index efc2a4b330d5064de5545eed14f4156d1c5bda28..4dddec73868bdbea27cdf4bcfc9f7ef096f65ccb 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2015-08-23  Carl Hetherington  <cth@carlh.net>
+
+       * Use correct fonts to render subtitles in preview (#663).
+
 2015-08-22  Carl Hetherington  <cth@carlh.net>
 
        * Version 2.1.44 released.
index 217f70fb27db0e20c3394df1114b1536fa17730a..0bde7b23f01a13704c304326bd43d83b7877d1dd 100644 (file)
@@ -21,6 +21,7 @@
 #define DCPOMATIC_IMAGE_SUBTITLE_H
 
 #include "rect.h"
+#include <boost/shared_ptr.hpp>
 
 class Image;
 
index d55c8d396cc48730c97b3a80b81d90faf6e5d1b4..48b298ff7bf485cb61d49648e6f4d28c0dd7e6e3 100644 (file)
@@ -213,6 +213,7 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
                property == SubtitleContentProperty::SUBTITLE_Y_OFFSET ||
                property == SubtitleContentProperty::SUBTITLE_X_SCALE ||
                property == SubtitleContentProperty::SUBTITLE_Y_SCALE ||
+               property == SubtitleContentProperty::FONTS ||
                property == VideoContentProperty::VIDEO_CROP ||
                property == VideoContentProperty::VIDEO_SCALE ||
                property == VideoContentProperty::VIDEO_FRAME_RATE ||
@@ -339,7 +340,7 @@ Player::get_video (DCPTime time, bool accurate)
 
        /* Text subtitles (rendered to an image) */
        if (!ps.text.empty ()) {
-               list<PositionImage> s = render_subtitles (ps.text, _video_container_size);
+               list<PositionImage> s = render_subtitles (ps.text, ps.fonts, _video_container_size);
                copy (s.begin (), s.end (), back_inserter (sub_images));
        }
 
@@ -606,6 +607,7 @@ Player::get_subtitles (DCPTime time, DCPTime length, bool starting, bool burnt)
                                        s.set_aspect_adjust (xs / ys);
                                }
                                ps.text.push_back (s);
+                               ps.add_fonts (subtitle_content->fonts ());
                        }
                }
        }
diff --git a/src/lib/player_subtitles.cc b/src/lib/player_subtitles.cc
new file mode 100644 (file)
index 0000000..da57143
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+
+    This program 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.
+
+    This program 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 this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "player_subtitles.h"
+#include "font.h"
+#include <boost/foreach.hpp>
+
+using std::list;
+using boost::shared_ptr;
+
+void
+PlayerSubtitles::add_fonts (list<shared_ptr<Font> > fonts_)
+{
+       BOOST_FOREACH (shared_ptr<Font> i, fonts_) {
+               bool got = false;
+               BOOST_FOREACH (shared_ptr<Font> j, fonts) {
+                       if (i->file() == j->file()) {
+                               got = true;
+                       }
+               }
+               if (!got) {
+                       fonts.push_back (i);
+               }
+       }
+}
index 93a0d5378775c30a769f8d01d5b9a987b5546a97..d6c19561e0628e40e8fdaa699dffed3b651dda8d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
 #define DCPOMATIC_PLAYER_SUBTITLES_H
 
 #include "image_subtitle.h"
+#include "dcpomatic_time.h"
 #include <dcp/subtitle_string.h>
 
+class Font;
+
 class PlayerSubtitles
 {
 public:
@@ -31,8 +34,11 @@ public:
                , to (t)
        {}
 
+       void add_fonts (std::list<boost::shared_ptr<Font> > fonts_);
+
        DCPTime from;
        DCPTime to;
+       std::list<boost::shared_ptr<Font> > fonts;
 
        /** ImageSubtitles, with their rectangles transformed as specified by their content */
        std::list<ImageSubtitle> image;
index 53f71328302c7d6dcfc193c8b905eb08010796d7..e29d0c75eb957d393404e4ce5c77accd7c7914df 100644 (file)
@@ -20,6 +20,8 @@
 #include "render_subtitles.h"
 #include "types.h"
 #include "image.h"
+#include "cross.h"
+#include "font.h"
 #include <cairomm/cairomm.h>
 #include <pangomm.h>
 #include <boost/foreach.hpp>
@@ -30,11 +32,15 @@ using std::string;
 using std::min;
 using std::max;
 using std::pair;
+using std::make_pair;
 using boost::shared_ptr;
 using boost::optional;
 
+static FcConfig* fc_config = 0;
+static list<pair<boost::filesystem::path, string> > fc_config_fonts;
+
 static PositionImage
-render_subtitle (dcp::SubtitleString const & subtitle, dcp::Size target)
+render_subtitle (dcp::SubtitleString const & subtitle, list<shared_ptr<Font> > fonts, dcp::Size target)
 {
        /* Calculate x and y scale factors.  These are only used to stretch
           the font away from its normal aspect ratio.
@@ -74,6 +80,59 @@ render_subtitle (dcp::SubtitleString const & subtitle, dcp::Size target)
                );
 
        Cairo::RefPtr<Cairo::Context> context = Cairo::Context::create (surface);
+
+       if (!fc_config) {
+               fc_config = FcConfigCreate ();
+       }
+
+       boost::filesystem::path font_file = shared_path () / "LiberationSans-Regular.ttf";
+       BOOST_FOREACH (shared_ptr<Font> i, fonts) {
+               if (i->id() == subtitle.font() && i->file ()) {
+                       font_file = i->file().get ();
+               }
+       }
+
+       list<pair<boost::filesystem::path, string> >::const_iterator existing = fc_config_fonts.begin ();
+       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 ()));
+
+               FcPattern* pattern = FcPatternBuild (0, FC_FILE, FcTypeString, font_file.string().c_str(), static_cast<char *> (0));
+               FcObjectSet* object_set = FcObjectSetBuild (FC_FAMILY, FC_STYLE, FC_LANG, FC_FILE, static_cast<char *> (0));
+               FcFontSet* 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);
+
        Glib::RefPtr<Pango::Layout> layout = Pango::Layout::create (context);
 
        layout->set_alignment (Pango::ALIGN_LEFT);
@@ -82,7 +141,7 @@ render_subtitle (dcp::SubtitleString const & subtitle, dcp::Size target)
 
        /* Render the subtitle at the top left-hand corner of image */
 
-       Pango::FontDescription font (subtitle.font().get_value_or ("Arial"));
+       Pango::FontDescription font (font_name);
        font.set_absolute_size (subtitle.size_in_pixels (target.height) * PANGO_SCALE);
        if (subtitle.italic ()) {
                font.set_style (Pango::STYLE_ITALIC);
@@ -164,11 +223,11 @@ render_subtitle (dcp::SubtitleString const & subtitle, dcp::Size target)
 }
 
 list<PositionImage>
-render_subtitles (list<dcp::SubtitleString> subtitles, dcp::Size target)
+render_subtitles (list<dcp::SubtitleString> subtitles, list<shared_ptr<Font> > fonts, dcp::Size target)
 {
        list<PositionImage> images;
        BOOST_FOREACH (dcp::SubtitleString const & i, subtitles) {
-               images.push_back (render_subtitle (i, target));
+               images.push_back (render_subtitle (i, fonts, target));
        }
        return images;
 }
index dbde8011594553b2dd2cf05ca96da4ebed42747e..22e5885ddec9f923e3b17abfce8a8e6a097ce1a7 100644 (file)
@@ -21,4 +21,6 @@
 #include <dcp/subtitle_string.h>
 #include <dcp/util.h>
 
-std::list<PositionImage> render_subtitles (std::list<dcp::SubtitleString>, dcp::Size);
+class Font;
+
+std::list<PositionImage> render_subtitles (std::list<dcp::SubtitleString>, std::list<boost::shared_ptr<Font> > fonts, dcp::Size);
index ef40c760662dc77725b7c3685d12abba62ae68f9..10ce61f8bc777237e50f5b59c10f325e89fe7689 100644 (file)
@@ -84,6 +84,7 @@ sources = """
           md5_digester.cc
           mid_side_decoder.cc
           player.cc
+          player_subtitles.cc
           player_video.cc
           playlist.cc
           position_image.cc