Rename Subtitle -> Text
authorCarl Hetherington <cth@carlh.net>
Mon, 11 Jun 2018 22:50:59 +0000 (23:50 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 19 Jul 2018 22:36:56 +0000 (23:36 +0100)
sed -i "s/SubtitleContent/TextContent/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc
sed -i "s/SubtitleDecoder/TextDecoder/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc
sed -i "s/subtitle_content/text_content/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc src/lib/wscript src/wx/wscript
sed -i "s/subtitle_decoder/text_decoder/g" src/lib/*.cc src/lib/*.h src/wx/*.cc src/wx/*.h src/tools/*.cc test/*.cc src/lib/wscript
mv src/lib/subtitle_decoder.cc src/lib/text_decoder.cc
mv src/lib/subtitle_decoder.h src/lib/text_decoder.h
mv src/lib/subtitle_content.cc src/lib/text_content.cc
mv src/lib/subtitle_content.h src/lib/text_content.h
mv src/lib/dcp_subtitle_decoder.cc src/lib/dcp_text_decoder.cc
mv src/lib/dcp_subtitle_decoder.h src/lib/dcp_text_decoder.h
mv src/lib/dcp_subtitle_content.cc src/lib/dcp_text_content.cc
mv src/lib/dcp_subtitle_content.h src/lib/dcp_text_content.h
mv src/lib/text_subtitle_content.cc src/lib/text_text_content.cc
mv src/lib/text_subtitle_content.h src/lib/text_text_content.h
mv src/lib/text_subtitle_decoder.cc src/lib/text_text_decoder.cc
mv src/lib/text_subtitle_decoder.h src/lib/text_text_decoder.h
mv src/wx/timeline_subtitle_content_view.cc src/wx/timeline_text_content_view.cc
mv src/wx/timeline_subtitle_content_view.h src/wx/timeline_text_content_view.h

77 files changed:
src/lib/active_subtitles.cc
src/lib/content.cc
src/lib/content.h
src/lib/content_factory.cc
src/lib/dcp_content.cc
src/lib/dcp_decoder.cc
src/lib/dcp_encoder.cc
src/lib/dcp_subtitle_content.cc [deleted file]
src/lib/dcp_subtitle_content.h [deleted file]
src/lib/dcp_subtitle_decoder.cc [deleted file]
src/lib/dcp_subtitle_decoder.h [deleted file]
src/lib/dcp_text_content.cc [new file with mode: 0644]
src/lib/dcp_text_content.h [new file with mode: 0644]
src/lib/dcp_text_decoder.cc [new file with mode: 0644]
src/lib/dcp_text_decoder.h [new file with mode: 0644]
src/lib/decoder.cc
src/lib/decoder.h
src/lib/decoder_factory.cc
src/lib/ffmpeg_content.cc
src/lib/ffmpeg_decoder.cc
src/lib/film.cc
src/lib/hints.cc
src/lib/image_subtitle.h
src/lib/player.cc
src/lib/playlist.cc
src/lib/subtitle_content.cc [deleted file]
src/lib/subtitle_content.h [deleted file]
src/lib/subtitle_decoder.cc [deleted file]
src/lib/subtitle_decoder.h [deleted file]
src/lib/text_content.cc [new file with mode: 0644]
src/lib/text_content.h [new file with mode: 0644]
src/lib/text_decoder.cc [new file with mode: 0644]
src/lib/text_decoder.h [new file with mode: 0644]
src/lib/text_file.cc [new file with mode: 0644]
src/lib/text_file.h [new file with mode: 0644]
src/lib/text_file_decoder.cc [new file with mode: 0644]
src/lib/text_file_decoder.h [new file with mode: 0644]
src/lib/text_subtitle.cc
src/lib/text_subtitle.h
src/lib/text_subtitle_content.cc [deleted file]
src/lib/text_subtitle_content.h [deleted file]
src/lib/text_subtitle_decoder.cc [deleted file]
src/lib/text_subtitle_decoder.h [deleted file]
src/lib/text_text_content.cc [new file with mode: 0644]
src/lib/text_text_content.h [new file with mode: 0644]
src/lib/text_text_decoder.cc [new file with mode: 0644]
src/lib/text_text_decoder.h [new file with mode: 0644]
src/lib/types.h
src/lib/wscript
src/tools/dcpomatic.cc
src/tools/dcpomatic_player.cc
src/wx/content_panel.cc
src/wx/dcp_panel.cc
src/wx/fonts_dialog.cc
src/wx/subtitle_appearance_dialog.cc
src/wx/subtitle_panel.cc
src/wx/subtitle_view.cc
src/wx/timeline.cc
src/wx/timeline_subtitle_content_view.cc [deleted file]
src/wx/timeline_subtitle_content_view.h [deleted file]
src/wx/timeline_text_content_view.cc [new file with mode: 0644]
src/wx/timeline_text_content_view.h [new file with mode: 0644]
src/wx/timing_panel.cc
src/wx/wscript
test/burnt_subtitle_test.cc
test/dcp_subtitle_test.cc
test/ffmpeg_encoder_test.cc
test/import_dcp_test.cc
test/player_test.cc
test/reels_test.cc
test/remake_id_test.cc
test/remake_with_subtitle_test.cc
test/srt_subtitle_test.cc
test/ssa_subtitle_test.cc
test/subtitle_reel_number_test.cc
test/subtitle_trim_test.cc
test/vf_kdm_test.cc

index bc34a89424b7464af3428ac0285d60d1db2f550a..f1d20179882948796130c6e8a728f9a4a6364d5f 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "active_subtitles.h"
 #include "piece.h"
 
 #include "active_subtitles.h"
 #include "piece.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 
index 2e4e77f8d6e6fcbcd3f5eb65bb0f99eab5aed818..1a8bc9eb20aabe80a9c395121d45d61ff4ea555e 100644 (file)
@@ -27,7 +27,7 @@
 #include "content_factory.h"
 #include "video_content.h"
 #include "audio_content.h"
 #include "content_factory.h"
 #include "video_content.h"
 #include "audio_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "exceptions.h"
 #include "film.h"
 #include "job.h"
 #include "exceptions.h"
 #include "film.h"
 #include "job.h"
index ea764907a2a2f6990b28f79b2efee9f42f8dd85f..63d03fd713121cdf3fadebe17390158e32fa9284 100644 (file)
@@ -182,7 +182,7 @@ public:
 
        boost::shared_ptr<VideoContent> video;
        boost::shared_ptr<AudioContent> audio;
 
        boost::shared_ptr<VideoContent> video;
        boost::shared_ptr<AudioContent> audio;
-       boost::shared_ptr<SubtitleContent> subtitle;
+       boost::shared_ptr<TextContent> subtitle;
 
        void signal_changed (int);
 
 
        void signal_changed (int);
 
index 51dc4e1b333d57e4c4308a22ef94ad38248091ec..14ca579e934593ccffac1fd165fce88eef84d80c 100644 (file)
@@ -26,9 +26,9 @@
 #include "audio_content.h"
 #include "image_content.h"
 #include "atmos_mxf_content.h"
 #include "audio_content.h"
 #include "image_content.h"
 #include "atmos_mxf_content.h"
-#include "text_subtitle_content.h"
+#include "text_text_content.h"
 #include "dcp_content.h"
 #include "dcp_content.h"
-#include "dcp_subtitle_content.h"
+#include "dcp_text_content.h"
 #include "util.h"
 #include "ffmpeg_audio_stream.h"
 #include "video_mxf_content.h"
 #include "util.h"
 #include "ffmpeg_audio_stream.h"
 #include "video_mxf_content.h"
@@ -88,11 +88,11 @@ content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, l
                        );
 
        } else if (type == "SubRip" || type == "TextSubtitle") {
                        );
 
        } else if (type == "SubRip" || type == "TextSubtitle") {
-               content.reset (new TextSubtitleContent (film, node, version));
+               content.reset (new TextTextContent (film, node, version));
        } else if (type == "DCP") {
                content.reset (new DCPContent (film, node, version));
        } else if (type == "DCPSubtitle") {
        } else if (type == "DCP") {
                content.reset (new DCPContent (film, node, version));
        } else if (type == "DCPSubtitle") {
-               content.reset (new DCPSubtitleContent (film, node, version));
+               content.reset (new DCPTextContent (film, node, version));
        } else if (type == "VideoMXF") {
                content.reset (new VideoMXFContent (film, node, version));
        } else if (type == "AtmosMXF") {
        } else if (type == "VideoMXF") {
                content.reset (new VideoMXFContent (film, node, version));
        } else if (type == "AtmosMXF") {
@@ -210,16 +210,16 @@ content_factory (shared_ptr<const Film> film, boost::filesystem::path path)
                if (valid_image_file (path)) {
                        single.reset (new ImageContent (film, path));
                } else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
                if (valid_image_file (path)) {
                        single.reset (new ImageContent (film, path));
                } else if (ext == ".srt" || ext == ".ssa" || ext == ".ass") {
-                       single.reset (new TextSubtitleContent (film, path));
+                       single.reset (new TextTextContent (film, path));
                } else if (ext == ".xml") {
                        cxml::Document doc;
                        doc.read_file (path);
                        if (doc.root_name() == "DCinemaSecurityMessage") {
                                throw KDMAsContentError ();
                        }
                } else if (ext == ".xml") {
                        cxml::Document doc;
                        doc.read_file (path);
                        if (doc.root_name() == "DCinemaSecurityMessage") {
                                throw KDMAsContentError ();
                        }
-                       single.reset (new DCPSubtitleContent (film, path));
+                       single.reset (new DCPTextContent (film, path));
                } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) {
                } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) {
-                       single.reset (new DCPSubtitleContent (film, path));
+                       single.reset (new DCPTextContent (film, path));
                } else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) {
                        single.reset (new VideoMXFContent (film, path));
                } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) {
                } else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) {
                        single.reset (new VideoMXFContent (film, path));
                } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) {
index ad1f07718d6d114346b59d9419fce1d658487e4b..d4891ad457849a4db38b2a94a7540abe23b9ce03 100644 (file)
@@ -28,7 +28,7 @@
 #include "overlaps.h"
 #include "compose.hpp"
 #include "dcp_decoder.h"
 #include "overlaps.h"
 #include "compose.hpp"
 #include "dcp_decoder.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include <dcp/dcp.h>
 #include <dcp/raw_convert.h>
 #include <dcp/exceptions.h>
 #include <dcp/dcp.h>
 #include <dcp/raw_convert.h>
 #include <dcp/exceptions.h>
@@ -81,7 +81,7 @@ DCPContent::DCPContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, in
 {
        video = VideoContent::from_xml (this, node, version);
        audio = AudioContent::from_xml (this, node, version);
 {
        video = VideoContent::from_xml (this, node, version);
        audio = AudioContent::from_xml (this, node, version);
-       subtitle = SubtitleContent::from_xml (this, node, version);
+       subtitle = TextContent::from_xml (this, node, version);
 
        if (video && audio) {
                audio->set_stream (
 
        if (video && audio) {
                audio->set_stream (
@@ -179,7 +179,7 @@ DCPContent::examine (shared_ptr<Job> job)
                boost::mutex::scoped_lock lm (_mutex);
                _name = examiner->name ();
                if (examiner->has_subtitles ()) {
                boost::mutex::scoped_lock lm (_mutex);
                _name = examiner->name ();
                if (examiner->has_subtitles ()) {
-                       subtitle.reset (new SubtitleContent (this));
+                       subtitle.reset (new TextContent (this));
                } else {
                        subtitle.reset ();
                }
                } else {
                        subtitle.reset ();
                }
index 9893cf7fc7318740aef7a8347b89219839e54d28..03bd95d90f8a7671131e23f108bdf1ab32acdeba 100644 (file)
@@ -24,7 +24,7 @@
 #include "video_decoder.h"
 #include "audio_decoder.h"
 #include "j2k_image_proxy.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
 #include "j2k_image_proxy.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
 #include "image.h"
 #include "config.h"
 #include <dcp/dcp.h>
 #include "image.h"
 #include "config.h"
 #include <dcp/dcp.h>
@@ -64,7 +64,7 @@ DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, boo
        }
        if (c->subtitle) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
        }
        if (c->subtitle) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
-               subtitle.reset (new SubtitleDecoder (this, c->subtitle, log, ContentTime()));
+               subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
        }
 
        list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
        }
 
        list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
index f1e819083a1728ffbf603386e52f0b5b5253dfd4..9121e9d53243551db4a5530cd27760221dcb155e 100644 (file)
@@ -35,7 +35,7 @@
 #include "writer.h"
 #include "compose.hpp"
 #include "referenced_reel_asset.h"
 #include "writer.h"
 #include "compose.hpp"
 #include "referenced_reel_asset.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "player_video.h"
 #include <boost/signals2.hpp>
 #include <boost/foreach.hpp>
 #include "player_video.h"
 #include <boost/signals2.hpp>
 #include <boost/foreach.hpp>
diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc
deleted file mode 100644 (file)
index 8fee0b2..0000000
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-    Copyright (C) 2014-2015 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 "font.h"
-#include "dcp_subtitle_content.h"
-#include "film.h"
-#include "subtitle_content.h"
-#include <dcp/raw_convert.h>
-#include <dcp/interop_subtitle_asset.h>
-#include <dcp/smpte_subtitle_asset.h>
-#include <dcp/interop_load_font_node.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-
-#include "i18n.h"
-
-using std::string;
-using std::list;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using dcp::raw_convert;
-
-DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
-       : Content (film, path)
-{
-       subtitle.reset (new SubtitleContent (this));
-}
-
-DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
-       : Content (film, node)
-       , _length (node->number_child<ContentTime::Type> ("Length"))
-{
-       subtitle = SubtitleContent::from_xml (this, node, version);
-}
-
-void
-DCPSubtitleContent::examine (shared_ptr<Job> job)
-{
-       Content::examine (job);
-
-       shared_ptr<dcp::SubtitleAsset> sc = load (path (0));
-
-       shared_ptr<dcp::InteropSubtitleAsset> iop = dynamic_pointer_cast<dcp::InteropSubtitleAsset> (sc);
-       shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
-       if (smpte) {
-               set_video_frame_rate (smpte->edit_rate().numerator);
-       }
-
-       boost::mutex::scoped_lock lm (_mutex);
-
-       /* Default to turning these subtitles on */
-       subtitle->set_use (true);
-
-       if (iop) {
-               subtitle->set_language (iop->language ());
-       } else if (smpte) {
-               subtitle->set_language (smpte->language().get_value_or (""));
-       }
-
-       _length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
-
-       BOOST_FOREACH (shared_ptr<dcp::LoadFontNode> i, sc->load_font_nodes ()) {
-               subtitle->add_font (shared_ptr<Font> (new Font (i->id)));
-       }
-}
-
-DCPTime
-DCPSubtitleContent::full_length () const
-{
-       FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate());
-       return DCPTime (_length, frc);
-}
-
-string
-DCPSubtitleContent::summary () const
-{
-       return path_summary() + " " + _("[subtitles]");
-}
-
-string
-DCPSubtitleContent::technical_summary () const
-{
-       return Content::technical_summary() + " - " + _("DCP XML subtitles");
-}
-
-void
-DCPSubtitleContent::as_xml (xmlpp::Node* node, bool with_paths) const
-{
-       node->add_child("Type")->add_child_text ("DCPSubtitle");
-       Content::as_xml (node, with_paths);
-
-       if (subtitle) {
-               subtitle->as_xml (node);
-       }
-
-       node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
-}
diff --git a/src/lib/dcp_subtitle_content.h b/src/lib/dcp_subtitle_content.h
deleted file mode 100644 (file)
index 36945ad..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
-    Copyright (C) 2014-2016 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 "dcp_subtitle.h"
-#include "content.h"
-
-class DCPSubtitleContent : public DCPSubtitle, public Content
-{
-public:
-       DCPSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
-       DCPSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
-
-       void examine (boost::shared_ptr<Job>);
-       std::string summary () const;
-       std::string technical_summary () const;
-       void as_xml (xmlpp::Node *, bool with_paths) const;
-       DCPTime full_length () const;
-
-private:
-       ContentTime _length;
-};
diff --git a/src/lib/dcp_subtitle_decoder.cc b/src/lib/dcp_subtitle_decoder.cc
deleted file mode 100644 (file)
index 46256e9..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-    Copyright (C) 2014-2018 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 "dcp_subtitle_decoder.h"
-#include "dcp_subtitle_content.h"
-#include <dcp/interop_subtitle_asset.h>
-#include <iostream>
-
-using std::list;
-using std::cout;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::bind;
-
-DCPSubtitleDecoder::DCPSubtitleDecoder (shared_ptr<const DCPSubtitleContent> content, shared_ptr<Log> log)
-{
-       shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
-       _subtitles = c->subtitles ();
-       _next = _subtitles.begin ();
-
-       ContentTime first;
-       if (_next != _subtitles.end()) {
-               first = content_time_period(*_next).from;
-       }
-       subtitle.reset (new SubtitleDecoder (this, content->subtitle, log, first));
-}
-
-void
-DCPSubtitleDecoder::seek (ContentTime time, bool accurate)
-{
-       Decoder::seek (time, accurate);
-
-       _next = _subtitles.begin ();
-       list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
-       while (i != _subtitles.end() && ContentTime::from_seconds ((*_next)->in().as_seconds()) < time) {
-               ++i;
-       }
-}
-
-bool
-DCPSubtitleDecoder::pass ()
-{
-       if (_next == _subtitles.end ()) {
-               return true;
-       }
-
-       /* Gather all subtitles with the same time period that are next
-          on the list.  We must emit all subtitles for the same time
-          period with the same text_subtitle() call otherwise the
-          SubtitleDecoder will assume there is nothing else at the
-          time of emit the first.
-       */
-
-       list<dcp::SubtitleString> s;
-       ContentTimePeriod const p = content_time_period (*_next);
-
-       while (_next != _subtitles.end () && content_time_period (*_next) == p) {
-               shared_ptr<dcp::SubtitleString> ns = dynamic_pointer_cast<dcp::SubtitleString>(*_next);
-               if (ns) {
-                       s.push_back (*ns);
-                       ++_next;
-               }
-
-               /* XXX: image subtitles */
-       }
-
-       subtitle->emit_text (p, s);
-       return false;
-}
-
-ContentTimePeriod
-DCPSubtitleDecoder::content_time_period (shared_ptr<dcp::Subtitle> s) const
-{
-       return ContentTimePeriod (
-               ContentTime::from_seconds (s->in().as_seconds ()),
-               ContentTime::from_seconds (s->out().as_seconds ())
-               );
-}
diff --git a/src/lib/dcp_subtitle_decoder.h b/src/lib/dcp_subtitle_decoder.h
deleted file mode 100644 (file)
index 0756a27..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-    Copyright (C) 2014 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 "subtitle_decoder.h"
-#include "dcp_subtitle.h"
-
-class DCPSubtitleContent;
-
-class DCPSubtitleDecoder : public DCPSubtitle, public Decoder
-{
-public:
-       DCPSubtitleDecoder (boost::shared_ptr<const DCPSubtitleContent>, boost::shared_ptr<Log> log);
-
-       bool pass ();
-       void seek (ContentTime time, bool accurate);
-
-private:
-       ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
-
-       std::list<boost::shared_ptr<dcp::Subtitle> > _subtitles;
-       std::list<boost::shared_ptr<dcp::Subtitle> >::const_iterator _next;
-};
diff --git a/src/lib/dcp_text_content.cc b/src/lib/dcp_text_content.cc
new file mode 100644 (file)
index 0000000..9e7524b
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+    Copyright (C) 2014-2015 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 "font.h"
+#include "dcp_text_content.h"
+#include "film.h"
+#include "text_content.h"
+#include <dcp/raw_convert.h>
+#include <dcp/interop_subtitle_asset.h>
+#include <dcp/smpte_subtitle_asset.h>
+#include <dcp/interop_load_font_node.h>
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+
+#include "i18n.h"
+
+using std::string;
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using dcp::raw_convert;
+
+DCPTextContent::DCPTextContent (shared_ptr<const Film> film, boost::filesystem::path path)
+       : Content (film, path)
+{
+       subtitle.reset (new TextContent (this));
+}
+
+DCPTextContent::DCPTextContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+       : Content (film, node)
+       , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+       subtitle = TextContent::from_xml (this, node, version);
+}
+
+void
+DCPTextContent::examine (shared_ptr<Job> job)
+{
+       Content::examine (job);
+
+       shared_ptr<dcp::SubtitleAsset> sc = load (path (0));
+
+       shared_ptr<dcp::InteropSubtitleAsset> iop = dynamic_pointer_cast<dcp::InteropSubtitleAsset> (sc);
+       shared_ptr<dcp::SMPTESubtitleAsset> smpte = dynamic_pointer_cast<dcp::SMPTESubtitleAsset> (sc);
+       if (smpte) {
+               set_video_frame_rate (smpte->edit_rate().numerator);
+       }
+
+       boost::mutex::scoped_lock lm (_mutex);
+
+       /* Default to turning these subtitles on */
+       subtitle->set_use (true);
+
+       if (iop) {
+               subtitle->set_language (iop->language ());
+       } else if (smpte) {
+               subtitle->set_language (smpte->language().get_value_or (""));
+       }
+
+       _length = ContentTime::from_seconds (sc->latest_subtitle_out().as_seconds ());
+
+       BOOST_FOREACH (shared_ptr<dcp::LoadFontNode> i, sc->load_font_nodes ()) {
+               subtitle->add_font (shared_ptr<Font> (new Font (i->id)));
+       }
+}
+
+DCPTime
+DCPTextContent::full_length () const
+{
+       FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate());
+       return DCPTime (_length, frc);
+}
+
+string
+DCPTextContent::summary () const
+{
+       return path_summary() + " " + _("[subtitles]");
+}
+
+string
+DCPTextContent::technical_summary () const
+{
+       return Content::technical_summary() + " - " + _("DCP XML subtitles");
+}
+
+void
+DCPTextContent::as_xml (xmlpp::Node* node, bool with_paths) const
+{
+       node->add_child("Type")->add_child_text ("DCPSubtitle");
+       Content::as_xml (node, with_paths);
+
+       if (subtitle) {
+               subtitle->as_xml (node);
+       }
+
+       node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
+}
diff --git a/src/lib/dcp_text_content.h b/src/lib/dcp_text_content.h
new file mode 100644 (file)
index 0000000..894cc03
--- /dev/null
@@ -0,0 +1,38 @@
+/*
+    Copyright (C) 2014-2016 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 "dcp_subtitle.h"
+#include "content.h"
+
+class DCPTextContent : public DCPSubtitle, public Content
+{
+public:
+       DCPTextContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+       DCPTextContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
+
+       void examine (boost::shared_ptr<Job>);
+       std::string summary () const;
+       std::string technical_summary () const;
+       void as_xml (xmlpp::Node *, bool with_paths) const;
+       DCPTime full_length () const;
+
+private:
+       ContentTime _length;
+};
diff --git a/src/lib/dcp_text_decoder.cc b/src/lib/dcp_text_decoder.cc
new file mode 100644 (file)
index 0000000..741bbb8
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+    Copyright (C) 2014-2018 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 "dcp_text_decoder.h"
+#include "dcp_text_content.h"
+#include <dcp/interop_subtitle_asset.h>
+#include <iostream>
+
+using std::list;
+using std::cout;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::bind;
+
+DCPTextDecoder::DCPTextDecoder (shared_ptr<const DCPTextContent> content, shared_ptr<Log> log)
+{
+       shared_ptr<dcp::SubtitleAsset> c (load (content->path (0)));
+       _subtitles = c->subtitles ();
+       _next = _subtitles.begin ();
+
+       ContentTime first;
+       if (_next != _subtitles.end()) {
+               first = content_time_period(*_next).from;
+       }
+       subtitle.reset (new TextDecoder (this, content->subtitle, log, first));
+}
+
+void
+DCPTextDecoder::seek (ContentTime time, bool accurate)
+{
+       Decoder::seek (time, accurate);
+
+       _next = _subtitles.begin ();
+       list<shared_ptr<dcp::Subtitle> >::const_iterator i = _subtitles.begin ();
+       while (i != _subtitles.end() && ContentTime::from_seconds ((*_next)->in().as_seconds()) < time) {
+               ++i;
+       }
+}
+
+bool
+DCPTextDecoder::pass ()
+{
+       if (_next == _subtitles.end ()) {
+               return true;
+       }
+
+       /* Gather all subtitles with the same time period that are next
+          on the list.  We must emit all subtitles for the same time
+          period with the same text_subtitle() call otherwise the
+          TextDecoder will assume there is nothing else at the
+          time of emit the first.
+       */
+
+       list<dcp::SubtitleString> s;
+       ContentTimePeriod const p = content_time_period (*_next);
+
+       while (_next != _subtitles.end () && content_time_period (*_next) == p) {
+               shared_ptr<dcp::SubtitleString> ns = dynamic_pointer_cast<dcp::SubtitleString>(*_next);
+               if (ns) {
+                       s.push_back (*ns);
+                       ++_next;
+               }
+
+               /* XXX: image subtitles */
+       }
+
+       subtitle->emit_text (p, s);
+       return false;
+}
+
+ContentTimePeriod
+DCPTextDecoder::content_time_period (shared_ptr<dcp::SubtitleString> s) const
+{
+       return ContentTimePeriod (
+               ContentTime::from_seconds (s->in().as_seconds ()),
+               ContentTime::from_seconds (s->out().as_seconds ())
+               );
+}
diff --git a/src/lib/dcp_text_decoder.h b/src/lib/dcp_text_decoder.h
new file mode 100644 (file)
index 0000000..f1b51b8
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+    Copyright (C) 2014 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 "text_decoder.h"
+#include "dcp_subtitle.h"
+
+class DCPTextContent;
+
+class DCPTextDecoder : public DCPSubtitle, public Decoder
+{
+public:
+       DCPTextDecoder (boost::shared_ptr<const DCPTextContent>, boost::shared_ptr<Log> log);
+
+       bool pass ();
+       void seek (ContentTime time, bool accurate);
+
+private:
+       ContentTimePeriod content_time_period (boost::shared_ptr<dcp::Subtitle> s) const;
+
+       std::list<boost::shared_ptr<dcp::Subtitle> > _subtitles;
+       std::list<boost::shared_ptr<dcp::Subtitle> >::const_iterator _next;
+};
index 502273de1e49f5a551110674a5d8284572dbe180..e7e6b8620e9332e0dc51f79f8c5d4e743f884758 100644 (file)
@@ -21,7 +21,7 @@
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
 #include <boost/optional.hpp>
 #include <iostream>
 
 #include <boost/optional.hpp>
 #include <iostream>
 
index d87ff610ac47d3a9eae2eb795ac072a397c26b3f..27f0b114144187e02acdc882bef93a0c8dfdb82c 100644 (file)
@@ -32,7 +32,7 @@
 class Decoded;
 class VideoDecoder;
 class AudioDecoder;
 class Decoded;
 class VideoDecoder;
 class AudioDecoder;
-class SubtitleDecoder;
+class TextDecoder;
 class DecoderPart;
 
 /** @class Decoder.
 class DecoderPart;
 
 /** @class Decoder.
@@ -45,7 +45,7 @@ public:
 
        boost::shared_ptr<VideoDecoder> video;
        boost::shared_ptr<AudioDecoder> audio;
 
        boost::shared_ptr<VideoDecoder> video;
        boost::shared_ptr<AudioDecoder> audio;
-       boost::shared_ptr<SubtitleDecoder> subtitle;
+       boost::shared_ptr<TextDecoder> subtitle;
 
        /** Do some decoding and perhaps emit video, audio or subtitle data.
         *  @return true if this decoder will emit no more data unless a seek() happens.
 
        /** Do some decoding and perhaps emit video, audio or subtitle data.
         *  @return true if this decoder will emit no more data unless a seek() happens.
index b675f9473331b88439b0ac5e80c17efbb614d07e..1a0af1b2c07cdfb834566f6ec5a470153f6015b6 100644 (file)
 #include "dcp_decoder.h"
 #include "image_content.h"
 #include "image_decoder.h"
 #include "dcp_decoder.h"
 #include "image_content.h"
 #include "image_decoder.h"
-#include "text_subtitle_content.h"
-#include "text_subtitle_decoder.h"
-#include "dcp_subtitle_content.h"
-#include "dcp_subtitle_decoder.h"
+#include "text_text_content.h"
+#include "text_text_decoder.h"
+#include "dcp_text_content.h"
+#include "dcp_text_decoder.h"
 #include "video_mxf_content.h"
 #include "video_mxf_decoder.h"
 #include <boost/foreach.hpp>
 #include "video_mxf_content.h"
 #include "video_mxf_decoder.h"
 #include <boost/foreach.hpp>
@@ -54,14 +54,14 @@ decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log, bool fa
                return shared_ptr<Decoder> (new ImageDecoder (ic, log));
        }
 
                return shared_ptr<Decoder> (new ImageDecoder (ic, log));
        }
 
-       shared_ptr<const TextSubtitleContent> rc = dynamic_pointer_cast<const TextSubtitleContent> (content);
+       shared_ptr<const TextTextContent> rc = dynamic_pointer_cast<const TextTextContent> (content);
        if (rc) {
        if (rc) {
-               return shared_ptr<Decoder> (new TextSubtitleDecoder (rc, log));
+               return shared_ptr<Decoder> (new TextTextDecoder (rc, log));
        }
 
        }
 
-       shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (content);
+       shared_ptr<const DCPTextContent> dsc = dynamic_pointer_cast<const DCPTextContent> (content);
        if (dsc) {
        if (dsc) {
-               return shared_ptr<Decoder> (new DCPSubtitleDecoder (dsc, log));
+               return shared_ptr<Decoder> (new DCPTextDecoder (dsc, log));
        }
 
        shared_ptr<const VideoMXFContent> vmc = dynamic_pointer_cast<const VideoMXFContent> (content);
        }
 
        shared_ptr<const VideoMXFContent> vmc = dynamic_pointer_cast<const VideoMXFContent> (content);
index cbeebd8178f0ba7c1e3f84a93b3230ae03e44f27..e18977944648fc1faff37e83987d8018a63fe473 100644 (file)
@@ -32,7 +32,7 @@
 #include "log.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
 #include "log.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include <dcp/raw_convert.h>
 #include <libcxml/cxml.h>
 extern "C" {
 #include <dcp/raw_convert.h>
 #include <libcxml/cxml.h>
 extern "C" {
@@ -85,7 +85,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, cxml::ConstNodePtr no
 {
        video = VideoContent::from_xml (this, node, version);
        audio = AudioContent::from_xml (this, node, version);
 {
        video = VideoContent::from_xml (this, node, version);
        audio = AudioContent::from_xml (this, node, version);
-       subtitle = SubtitleContent::from_xml (this, node, version);
+       subtitle = TextContent::from_xml (this, node, version);
 
        list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
        for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
 
        list<cxml::NodePtr> c = node->node_children ("SubtitleStream");
        for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) {
@@ -163,7 +163,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Con
                audio.reset (new AudioContent (this, c));
        }
        if (need_subtitle) {
                audio.reset (new AudioContent (this, c));
        }
        if (need_subtitle) {
-               subtitle.reset (new SubtitleContent (this, c));
+               subtitle.reset (new TextContent (this, c));
        }
 
        shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
        }
 
        shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
@@ -303,7 +303,7 @@ FFmpegContent::examine (shared_ptr<Job> job)
 
                _subtitle_streams = examiner->subtitle_streams ();
                if (!_subtitle_streams.empty ()) {
 
                _subtitle_streams = examiner->subtitle_streams ();
                if (!_subtitle_streams.empty ()) {
-                       subtitle.reset (new SubtitleContent (this));
+                       subtitle.reset (new TextContent (this));
                        _subtitle_stream = _subtitle_streams.front ();
                }
 
                        _subtitle_stream = _subtitle_streams.front ();
                }
 
index 0746458e58fd5be806a75566b398772ad33ff618..4d10f8ef7400069332ccdde4c08be5172ce642f2 100644 (file)
@@ -28,7 +28,7 @@
 #include "util.h"
 #include "log.h"
 #include "ffmpeg_decoder.h"
 #include "util.h"
 #include "log.h"
 #include "ffmpeg_decoder.h"
-#include "subtitle_decoder.h"
+#include "text_decoder.h"
 #include "ffmpeg_audio_stream.h"
 #include "ffmpeg_subtitle_stream.h"
 #include "video_filter_graph.h"
 #include "ffmpeg_audio_stream.h"
 #include "ffmpeg_subtitle_stream.h"
 #include "video_filter_graph.h"
@@ -39,7 +39,7 @@
 #include "film.h"
 #include "audio_decoder.h"
 #include "compose.hpp"
 #include "film.h"
 #include "audio_decoder.h"
 #include "compose.hpp"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "audio_content.h"
 #include <dcp/subtitle_string.h>
 #include <sub/ssa_reader.h>
 #include "audio_content.h"
 #include <dcp/subtitle_string.h>
 #include <sub/ssa_reader.h>
@@ -99,7 +99,7 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log>
 
        if (c->subtitle) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
 
        if (c->subtitle) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
-               subtitle.reset (new SubtitleDecoder (this, c->subtitle, log, ContentTime()));
+               subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
        }
 
        _next_time.resize (_format_context->nb_streams);
        }
 
        _next_time.resize (_format_context->nb_streams);
index 98ae2e59b1b753605f391d4ca73744da9c4db6b8..0be1ddd7b71a19161c44f6957f63c5a3aae23213 100644 (file)
@@ -46,7 +46,7 @@
 #include "screen.h"
 #include "audio_content.h"
 #include "video_content.h"
 #include "screen.h"
 #include "audio_content.h"
 #include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "ffmpeg_content.h"
 #include "dcp_content.h"
 #include "screen_kdm.h"
 #include "ffmpeg_content.h"
 #include "dcp_content.h"
 #include "screen_kdm.h"
index 91aabdd56622e3939d934fcfc858dfbc1259298e..d29002ad56273e8fb51f94b61a29d2ffa5ee9881 100644 (file)
@@ -23,7 +23,7 @@
 #include "film.h"
 #include "content.h"
 #include "video_content.h"
 #include "film.h"
 #include "content.h"
 #include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "audio_processor.h"
 #include "font.h"
 #include "ratio.h"
 #include "audio_processor.h"
 #include "font.h"
 #include "ratio.h"
index f82c5b1944a3dac58af150ab8b4dbcc53b937366..e0687e5817783b0858eadbe448887e0ae58042f3 100644 (file)
@@ -39,7 +39,7 @@ public:
         *  proportions of the image size; e.g. rectangle.x = 0.5 would mean that
         *  the rectangle starts half-way across the video.
         *
         *  proportions of the image size; e.g. rectangle.x = 0.5 would mean that
         *  the rectangle starts half-way across the video.
         *
-        *  This rectangle may or may not have had a SubtitleContent's offsets and
+        *  This rectangle may or may not have had a TextContent's offsets and
         *  scale applied to it, depending on context.
         */
        dcpomatic::Rect<double> rectangle;
         *  scale applied to it, depending on context.
         */
        dcpomatic::Rect<double> rectangle;
index df58ed223af0ea043322f5a2e42262dc0466656a..b701deb5eb59fdbcd205a632de46bd5f933e3239 100644 (file)
@@ -40,8 +40,8 @@
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
-#include "subtitle_content.h"
-#include "subtitle_decoder.h"
+#include "text_content.h"
+#include "text_decoder.h"
 #include "ffmpeg_content.h"
 #include "audio_content.h"
 #include "content_subtitle.h"
 #include "ffmpeg_content.h"
 #include "audio_content.h"
 #include "content_subtitle.h"
@@ -210,9 +210,9 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
                property == AudioContentProperty::STREAMS ||
                property == DCPContentProperty::NEEDS_ASSETS ||
                property == DCPContentProperty::NEEDS_KDM ||
                property == AudioContentProperty::STREAMS ||
                property == DCPContentProperty::NEEDS_ASSETS ||
                property == DCPContentProperty::NEEDS_KDM ||
-               property == SubtitleContentProperty::COLOUR ||
-               property == SubtitleContentProperty::EFFECT ||
-               property == SubtitleContentProperty::EFFECT_COLOUR ||
+               property == TextContentProperty::COLOUR ||
+               property == TextContentProperty::EFFECT ||
+               property == TextContentProperty::EFFECT_COLOUR ||
                property == FFmpegContentProperty::SUBTITLE_STREAM ||
                property == FFmpegContentProperty::FILTERS
                ) {
                property == FFmpegContentProperty::SUBTITLE_STREAM ||
                property == FFmpegContentProperty::FILTERS
                ) {
@@ -221,17 +221,17 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
                Changed (property, frequent);
 
        } else if (
                Changed (property, frequent);
 
        } else if (
-               property == SubtitleContentProperty::LINE_SPACING ||
-               property == SubtitleContentProperty::OUTLINE_WIDTH ||
-               property == SubtitleContentProperty::Y_SCALE ||
-               property == SubtitleContentProperty::FADE_IN ||
-               property == SubtitleContentProperty::FADE_OUT ||
+               property == TextContentProperty::LINE_SPACING ||
+               property == TextContentProperty::OUTLINE_WIDTH ||
+               property == TextContentProperty::Y_SCALE ||
+               property == TextContentProperty::FADE_IN ||
+               property == TextContentProperty::FADE_OUT ||
                property == ContentProperty::VIDEO_FRAME_RATE ||
                property == ContentProperty::VIDEO_FRAME_RATE ||
-               property == SubtitleContentProperty::USE ||
-               property == SubtitleContentProperty::X_OFFSET ||
-               property == SubtitleContentProperty::Y_OFFSET ||
-               property == SubtitleContentProperty::X_SCALE ||
-               property == SubtitleContentProperty::FONTS ||
+               property == TextContentProperty::USE ||
+               property == TextContentProperty::X_OFFSET ||
+               property == TextContentProperty::Y_OFFSET ||
+               property == TextContentProperty::X_SCALE ||
+               property == TextContentProperty::FONTS ||
                property == VideoContentProperty::CROP ||
                property == VideoContentProperty::SCALE ||
                property == VideoContentProperty::FADE_IN ||
                property == VideoContentProperty::CROP ||
                property == VideoContentProperty::SCALE ||
                property == VideoContentProperty::FADE_IN ||
index 3376a55eab9079b2c422381578401e77c6976919..13b4d7337212a6a34be6d3fd89ad39e8d832935e 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "playlist.h"
 #include "video_content.h"
 
 #include "playlist.h"
 #include "video_content.h"
-#include "subtitle_content.h"
+#include "text_content.h"
 #include "ffmpeg_decoder.h"
 #include "ffmpeg_content.h"
 #include "image_decoder.h"
 #include "ffmpeg_decoder.h"
 #include "ffmpeg_content.h"
 #include "image_decoder.h"
diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc
deleted file mode 100644 (file)
index cd93638..0000000
+++ /dev/null
@@ -1,515 +0,0 @@
-/*
-    Copyright (C) 2013-2018 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 "subtitle_content.h"
-#include "util.h"
-#include "exceptions.h"
-#include "font.h"
-#include "content.h"
-#include <dcp/raw_convert.h>
-#include <libcxml/cxml.h>
-#include <libxml++/libxml++.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::vector;
-using std::cout;
-using std::list;
-using boost::shared_ptr;
-using boost::dynamic_pointer_cast;
-using boost::optional;
-using dcp::raw_convert;
-
-int const SubtitleContentProperty::X_OFFSET = 500;
-int const SubtitleContentProperty::Y_OFFSET = 501;
-int const SubtitleContentProperty::X_SCALE = 502;
-int const SubtitleContentProperty::Y_SCALE = 503;
-int const SubtitleContentProperty::USE = 504;
-int const SubtitleContentProperty::BURN = 505;
-int const SubtitleContentProperty::LANGUAGE = 506;
-int const SubtitleContentProperty::FONTS = 507;
-int const SubtitleContentProperty::COLOUR = 508;
-int const SubtitleContentProperty::EFFECT = 509;
-int const SubtitleContentProperty::EFFECT_COLOUR = 510;
-int const SubtitleContentProperty::LINE_SPACING = 511;
-int const SubtitleContentProperty::FADE_IN = 512;
-int const SubtitleContentProperty::FADE_OUT = 513;
-int const SubtitleContentProperty::OUTLINE_WIDTH = 514;
-
-SubtitleContent::SubtitleContent (Content* parent)
-       : ContentPart (parent)
-       , _use (false)
-       , _burn (false)
-       , _x_offset (0)
-       , _y_offset (0)
-       , _x_scale (1)
-       , _y_scale (1)
-       , _line_spacing (1)
-       , _outline_width (2)
-{
-
-}
-
-shared_ptr<SubtitleContent>
-SubtitleContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
-{
-       if (version < 34) {
-               /* With old metadata FFmpeg content has the subtitle-related tags even with no
-                  subtitle streams, so check for that.
-               */
-               if (node->string_child("Type") == "FFmpeg" && node->node_children("SubtitleStream").empty()) {
-                       return shared_ptr<SubtitleContent> ();
-               }
-
-               /* Otherwise we can drop through to the newer logic */
-       }
-
-       if (!node->optional_number_child<double>("SubtitleXOffset") && !node->optional_number_child<double>("SubtitleOffset")) {
-               return shared_ptr<SubtitleContent> ();
-       }
-
-       return shared_ptr<SubtitleContent> (new SubtitleContent (parent, node, version));
-}
-
-SubtitleContent::SubtitleContent (Content* parent, cxml::ConstNodePtr node, int version)
-       : ContentPart (parent)
-       , _use (false)
-       , _burn (false)
-       , _x_offset (0)
-       , _y_offset (0)
-       , _x_scale (1)
-       , _y_scale (1)
-       , _line_spacing (node->optional_number_child<double>("LineSpacing").get_value_or (1))
-       , _outline_width (node->optional_number_child<int>("OutlineWidth").get_value_or (2))
-{
-       if (version >= 32) {
-               _use = node->bool_child ("UseSubtitles");
-               _burn = node->bool_child ("BurnSubtitles");
-       }
-
-       if (version >= 7) {
-               _x_offset = node->number_child<double> ("SubtitleXOffset");
-               _y_offset = node->number_child<double> ("SubtitleYOffset");
-       } else {
-               _y_offset = node->number_child<double> ("SubtitleOffset");
-       }
-
-       if (node->optional_bool_child("Outline").get_value_or(false)) {
-               _effect = dcp::BORDER;
-       } else if (node->optional_bool_child("Shadow").get_value_or(false)) {
-               _effect = dcp::SHADOW;
-       } else {
-               _effect = dcp::NONE;
-       }
-
-       optional<string> effect = node->optional_string_child("Effect");
-       if (effect) {
-               if (*effect == "none") {
-                       _effect = dcp::NONE;
-               } else if (*effect == "outline") {
-                       _effect = dcp::BORDER;
-               } else if (*effect == "shadow") {
-                       _effect = dcp::SHADOW;
-               }
-       }
-
-       if (version >= 10) {
-               _x_scale = node->number_child<double> ("SubtitleXScale");
-               _y_scale = node->number_child<double> ("SubtitleYScale");
-       } else {
-               _x_scale = _y_scale = node->number_child<double> ("SubtitleScale");
-       }
-
-       optional<int> r = node->optional_number_child<int>("Red");
-       optional<int> g = node->optional_number_child<int>("Green");
-       optional<int> b = node->optional_number_child<int>("Blue");
-       if (r && g && b) {
-               _colour = dcp::Colour (*r, *g, *b);
-       }
-
-       if (version >= 36) {
-               optional<int> er = node->optional_number_child<int>("EffectRed");
-               optional<int> eg = node->optional_number_child<int>("EffectGreen");
-               optional<int> eb = node->optional_number_child<int>("EffectBlue");
-               if (er && eg && eb) {
-                       _effect_colour = dcp::Colour (*er, *eg, *eb);
-               }
-       } else {
-               _effect_colour = dcp::Colour (
-                       node->optional_number_child<int>("OutlineRed").get_value_or(255),
-                       node->optional_number_child<int>("OutlineGreen").get_value_or(255),
-                       node->optional_number_child<int>("OutlineBlue").get_value_or(255)
-                       );
-       }
-
-       optional<Frame> fi = node->optional_number_child<Frame>("SubtitleFadeIn");
-       if (fi) {
-               _fade_in = ContentTime (*fi);
-       }
-       optional<Frame> fo = node->optional_number_child<Frame>("SubtitleFadeOut");
-       if (fo) {
-               _fade_out = ContentTime (*fo);
-       }
-
-       _language = node->optional_string_child ("SubtitleLanguage").get_value_or ("");
-
-       list<cxml::NodePtr> fonts = node->node_children ("Font");
-       for (list<cxml::NodePtr>::const_iterator i = fonts.begin(); i != fonts.end(); ++i) {
-               _fonts.push_back (shared_ptr<Font> (new Font (*i)));
-       }
-
-       connect_to_fonts ();
-}
-
-SubtitleContent::SubtitleContent (Content* parent, vector<shared_ptr<Content> > c)
-       : ContentPart (parent)
-{
-       shared_ptr<SubtitleContent> ref = c[0]->subtitle;
-       DCPOMATIC_ASSERT (ref);
-       list<shared_ptr<Font> > ref_fonts = ref->fonts ();
-
-       for (size_t i = 1; i < c.size(); ++i) {
-
-               if (c[i]->subtitle->use() != ref->use()) {
-                       throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
-               }
-
-               if (c[i]->subtitle->burn() != ref->burn()) {
-                       throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
-               }
-
-               if (c[i]->subtitle->x_offset() != ref->x_offset()) {
-                       throw JoinError (_("Content to be joined must have the same subtitle X offset."));
-               }
-
-               if (c[i]->subtitle->y_offset() != ref->y_offset()) {
-                       throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
-               }
-
-               if (c[i]->subtitle->x_scale() != ref->x_scale()) {
-                       throw JoinError (_("Content to be joined must have the same subtitle X scale."));
-               }
-
-               if (c[i]->subtitle->y_scale() != ref->y_scale()) {
-                       throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
-               }
-
-               if (c[i]->subtitle->line_spacing() != ref->line_spacing()) {
-                       throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
-               }
-
-               if ((c[i]->subtitle->fade_in() != ref->fade_in()) || (c[i]->subtitle->fade_out() != ref->fade_out())) {
-                       throw JoinError (_("Content to be joined must have the same subtitle fades."));
-               }
-
-               if ((c[i]->subtitle->outline_width() != ref->outline_width())) {
-                       throw JoinError (_("Content to be joined must have the same outline width."));
-               }
-
-               list<shared_ptr<Font> > fonts = c[i]->subtitle->fonts ();
-               if (fonts.size() != ref_fonts.size()) {
-                       throw JoinError (_("Content to be joined must use the same fonts."));
-               }
-
-               list<shared_ptr<Font> >::const_iterator j = ref_fonts.begin ();
-               list<shared_ptr<Font> >::const_iterator k = fonts.begin ();
-
-               while (j != ref_fonts.end ()) {
-                       if (**j != **k) {
-                               throw JoinError (_("Content to be joined must use the same fonts."));
-                       }
-                       ++j;
-                       ++k;
-               }
-       }
-
-       _use = ref->use ();
-       _burn = ref->burn ();
-       _x_offset = ref->x_offset ();
-       _y_offset = ref->y_offset ();
-       _x_scale = ref->x_scale ();
-       _y_scale = ref->y_scale ();
-       _language = ref->language ();
-       _fonts = ref_fonts;
-       _line_spacing = ref->line_spacing ();
-       _fade_in = ref->fade_in ();
-       _fade_out = ref->fade_out ();
-       _outline_width = ref->outline_width ();
-
-       connect_to_fonts ();
-}
-
-/** _mutex must not be held on entry */
-void
-SubtitleContent::as_xml (xmlpp::Node* root) const
-{
-       boost::mutex::scoped_lock lm (_mutex);
-
-       root->add_child("UseSubtitles")->add_child_text (_use ? "1" : "0");
-       root->add_child("BurnSubtitles")->add_child_text (_burn ? "1" : "0");
-       root->add_child("SubtitleXOffset")->add_child_text (raw_convert<string> (_x_offset));
-       root->add_child("SubtitleYOffset")->add_child_text (raw_convert<string> (_y_offset));
-       root->add_child("SubtitleXScale")->add_child_text (raw_convert<string> (_x_scale));
-       root->add_child("SubtitleYScale")->add_child_text (raw_convert<string> (_y_scale));
-       root->add_child("SubtitleLanguage")->add_child_text (_language);
-       if (_colour) {
-               root->add_child("Red")->add_child_text (raw_convert<string> (_colour->r));
-               root->add_child("Green")->add_child_text (raw_convert<string> (_colour->g));
-               root->add_child("Blue")->add_child_text (raw_convert<string> (_colour->b));
-       }
-       if (_effect) {
-               switch (*_effect) {
-               case dcp::NONE:
-                       root->add_child("Effect")->add_child_text("none");
-                       break;
-               case dcp::BORDER:
-                       root->add_child("Effect")->add_child_text("outline");
-                       break;
-               case dcp::SHADOW:
-                       root->add_child("Effect")->add_child_text("shadow");
-                       break;
-               }
-       }
-       if (_effect_colour) {
-               root->add_child("EffectRed")->add_child_text (raw_convert<string> (_effect_colour->r));
-               root->add_child("EffectGreen")->add_child_text (raw_convert<string> (_effect_colour->g));
-               root->add_child("EffectBlue")->add_child_text (raw_convert<string> (_effect_colour->b));
-       }
-       root->add_child("LineSpacing")->add_child_text (raw_convert<string> (_line_spacing));
-       if (_fade_in) {
-               root->add_child("SubtitleFadeIn")->add_child_text (raw_convert<string> (_fade_in->get()));
-       }
-       if (_fade_out) {
-               root->add_child("SubtitleFadeOut")->add_child_text (raw_convert<string> (_fade_out->get()));
-       }
-       root->add_child("OutlineWidth")->add_child_text (raw_convert<string> (_outline_width));
-
-       for (list<shared_ptr<Font> >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
-               (*i)->as_xml (root->add_child("Font"));
-       }
-}
-
-string
-SubtitleContent::identifier () const
-{
-       string s = raw_convert<string> (x_scale())
-               + "_" + raw_convert<string> (y_scale())
-               + "_" + raw_convert<string> (x_offset())
-               + "_" + raw_convert<string> (y_offset())
-               + "_" + raw_convert<string> (line_spacing())
-               + "_" + raw_convert<string> (fade_in().get_value_or(ContentTime()).get())
-               + "_" + raw_convert<string> (fade_out().get_value_or(ContentTime()).get())
-               + "_" + raw_convert<string> (outline_width())
-               + "_" + raw_convert<string> (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string())
-               + "_" + raw_convert<string> (dcp::effect_to_string(effect().get_value_or(dcp::NONE)))
-               + "_" + raw_convert<string> (effect_colour().get_value_or(dcp::Colour(0, 0, 0)).to_argb_string());
-
-       /* XXX: I suppose really _fonts shouldn't be in here, since not all
-          types of subtitle content involve fonts.
-       */
-       BOOST_FOREACH (shared_ptr<Font> f, _fonts) {
-               for (int i = 0; i < FontFiles::VARIANTS; ++i) {
-                       s += "_" + f->file(static_cast<FontFiles::Variant>(i)).get_value_or("Default").string();
-               }
-       }
-
-       /* The language is for metadata only, and doesn't affect
-          how this content looks.
-       */
-
-       return s;
-}
-
-void
-SubtitleContent::add_font (shared_ptr<Font> font)
-{
-       _fonts.push_back (font);
-       connect_to_fonts ();
-}
-
-void
-SubtitleContent::connect_to_fonts ()
-{
-       BOOST_FOREACH (boost::signals2::connection& i, _font_connections) {
-               i.disconnect ();
-       }
-
-       _font_connections.clear ();
-
-       BOOST_FOREACH (shared_ptr<Font> i, _fonts) {
-               _font_connections.push_back (i->Changed.connect (boost::bind (&SubtitleContent::font_changed, this)));
-       }
-}
-
-void
-SubtitleContent::font_changed ()
-{
-       _parent->signal_changed (SubtitleContentProperty::FONTS);
-}
-
-void
-SubtitleContent::set_colour (dcp::Colour colour)
-{
-       maybe_set (_colour, colour, SubtitleContentProperty::COLOUR);
-}
-
-void
-SubtitleContent::unset_colour ()
-{
-       maybe_set (_colour, optional<dcp::Colour>(), SubtitleContentProperty::COLOUR);
-}
-
-void
-SubtitleContent::set_effect (dcp::Effect e)
-{
-       maybe_set (_effect, e, SubtitleContentProperty::EFFECT);
-}
-
-void
-SubtitleContent::unset_effect ()
-{
-       maybe_set (_effect, optional<dcp::Effect>(), SubtitleContentProperty::EFFECT);
-}
-
-void
-SubtitleContent::set_effect_colour (dcp::Colour colour)
-{
-       maybe_set (_effect_colour, colour, SubtitleContentProperty::EFFECT_COLOUR);
-}
-
-void
-SubtitleContent::unset_effect_colour ()
-{
-       maybe_set (_effect_colour, optional<dcp::Colour>(), SubtitleContentProperty::EFFECT_COLOUR);
-}
-
-void
-SubtitleContent::set_use (bool u)
-{
-       maybe_set (_use, u, SubtitleContentProperty::USE);
-}
-
-void
-SubtitleContent::set_burn (bool b)
-{
-       maybe_set (_burn, b, SubtitleContentProperty::BURN);
-}
-
-void
-SubtitleContent::set_x_offset (double o)
-{
-       maybe_set (_x_offset, o, SubtitleContentProperty::X_OFFSET);
-}
-
-void
-SubtitleContent::set_y_offset (double o)
-{
-       maybe_set (_y_offset, o, SubtitleContentProperty::Y_OFFSET);
-}
-
-void
-SubtitleContent::set_x_scale (double s)
-{
-       maybe_set (_x_scale, s, SubtitleContentProperty::X_SCALE);
-}
-
-void
-SubtitleContent::set_y_scale (double s)
-{
-       maybe_set (_y_scale, s, SubtitleContentProperty::Y_SCALE);
-}
-
-void
-SubtitleContent::set_language (string language)
-{
-       maybe_set (_language, language, SubtitleContentProperty::LANGUAGE);
-}
-
-void
-SubtitleContent::set_line_spacing (double s)
-{
-       maybe_set (_line_spacing, s, SubtitleContentProperty::LINE_SPACING);
-}
-
-void
-SubtitleContent::set_fade_in (ContentTime t)
-{
-       maybe_set (_fade_in, t, SubtitleContentProperty::FADE_IN);
-}
-
-void
-SubtitleContent::unset_fade_in ()
-{
-       maybe_set (_fade_in, optional<ContentTime>(), SubtitleContentProperty::FADE_IN);
-}
-
-void
-SubtitleContent::set_fade_out (ContentTime t)
-{
-       maybe_set (_fade_out, t, SubtitleContentProperty::FADE_OUT);
-}
-
-void
-SubtitleContent::unset_fade_out ()
-{
-       maybe_set (_fade_out, optional<ContentTime>(), SubtitleContentProperty::FADE_OUT);
-}
-
-void
-SubtitleContent::set_outline_width (int w)
-{
-       maybe_set (_outline_width, w, SubtitleContentProperty::OUTLINE_WIDTH);
-}
-
-void
-SubtitleContent::take_settings_from (shared_ptr<const SubtitleContent> c)
-{
-       set_use (c->_use);
-       set_burn (c->_burn);
-       set_x_offset (c->_x_offset);
-       set_y_offset (c->_y_offset);
-       set_x_scale (c->_x_scale);
-       set_y_scale (c->_y_scale);
-       maybe_set (_fonts, c->_fonts, SubtitleContentProperty::FONTS);
-       if (c->_colour) {
-               set_colour (*c->_colour);
-       } else {
-               unset_colour ();
-       }
-       if (c->_effect) {
-               set_effect (*c->_effect);
-       }
-       if (c->_effect_colour) {
-               set_effect_colour (*c->_effect_colour);
-       } else {
-               unset_effect_colour ();
-       }
-       set_line_spacing (c->_line_spacing);
-       if (c->_fade_in) {
-               set_fade_in (*c->_fade_in);
-       }
-       if (c->_fade_out) {
-               set_fade_out (*c->_fade_out);
-       }
-       set_outline_width (c->_outline_width);
-}
diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h
deleted file mode 100644 (file)
index b64e478..0000000
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
-    Copyright (C) 2013-2018 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/>.
-
-*/
-
-#ifndef DCPOMATIC_SUBTITLE_CONTENT_H
-#define DCPOMATIC_SUBTITLE_CONTENT_H
-
-#include "content_part.h"
-#include <libcxml/cxml.h>
-#include <dcp/types.h>
-#include <boost/signals2.hpp>
-
-class Font;
-
-class SubtitleContentProperty
-{
-public:
-       static int const X_OFFSET;
-       static int const Y_OFFSET;
-       static int const X_SCALE;
-       static int const Y_SCALE;
-       static int const USE;
-       static int const BURN;
-       static int const LANGUAGE;
-       static int const FONTS;
-       static int const COLOUR;
-       static int const EFFECT;
-       static int const EFFECT_COLOUR;
-       static int const LINE_SPACING;
-       static int const FADE_IN;
-       static int const FADE_OUT;
-       static int const OUTLINE_WIDTH;
-};
-
-/** @class SubtitleContent
- *  @brief Description of how some subtitle content should be presented.
- *
- *  There are `image' subtitles (bitmaps) and `text' subtitles (plain text),
- *  and not all of the settings in this class correspond to both types.
- */
-class SubtitleContent : public ContentPart
-{
-public:
-       explicit SubtitleContent (Content* parent);
-       SubtitleContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
-
-       void as_xml (xmlpp::Node *) const;
-       std::string identifier () const;
-       void take_settings_from (boost::shared_ptr<const SubtitleContent> c);
-
-       void add_font (boost::shared_ptr<Font> font);
-
-       void set_use (bool);
-       void set_burn (bool);
-       void set_x_offset (double);
-       void set_y_offset (double);
-       void set_x_scale (double);
-       void set_y_scale (double);
-       void set_language (std::string language);
-       void set_colour (dcp::Colour);
-       void unset_colour ();
-       void set_effect (dcp::Effect);
-       void unset_effect ();
-       void set_effect_colour (dcp::Colour);
-       void unset_effect_colour ();
-       void set_line_spacing (double s);
-       void set_fade_in (ContentTime);
-       void unset_fade_in ();
-       void set_fade_out (ContentTime);
-       void set_outline_width (int);
-       void unset_fade_out ();
-
-       bool use () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _use;
-       }
-
-       bool burn () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _burn;
-       }
-
-       double x_offset () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _x_offset;
-       }
-
-       double y_offset () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _y_offset;
-       }
-
-       double x_scale () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _x_scale;
-       }
-
-       double y_scale () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _y_scale;
-       }
-
-       std::list<boost::shared_ptr<Font> > fonts () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _fonts;
-       }
-
-       std::string language () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _language;
-       }
-
-       boost::optional<dcp::Colour> colour () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _colour;
-       }
-
-       boost::optional<dcp::Effect> effect () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _effect;
-       }
-
-       boost::optional<dcp::Colour> effect_colour () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _effect_colour;
-       }
-
-       double line_spacing () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _line_spacing;
-       }
-
-       boost::optional<ContentTime> fade_in () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _fade_in;
-       }
-
-       boost::optional<ContentTime> fade_out () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _fade_out;
-       }
-
-       int outline_width () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _outline_width;
-       }
-
-       static boost::shared_ptr<SubtitleContent> from_xml (Content* parent, cxml::ConstNodePtr, int version);
-
-protected:
-       /** subtitle language (e.g. "German") or empty if it is not known */
-       std::string _language;
-
-private:
-       friend struct ffmpeg_pts_offset_test;
-
-       SubtitleContent (Content* parent, cxml::ConstNodePtr, int version);
-       void font_changed ();
-       void connect_to_fonts ();
-
-       std::list<boost::signals2::connection> _font_connections;
-
-       bool _use;
-       bool _burn;
-       /** x offset for placing subtitles, as a proportion of the container width;
-        * +ve is further right, -ve is further left.
-        */
-       double _x_offset;
-       /** y offset for placing subtitles, as a proportion of the container height;
-        *  +ve is further down the frame, -ve is further up.
-        */
-       double _y_offset;
-       /** x scale factor to apply to subtitles */
-       double _x_scale;
-       /** y scale factor to apply to subtitles */
-       double _y_scale;
-       std::list<boost::shared_ptr<Font> > _fonts;
-       boost::optional<dcp::Colour> _colour;
-       boost::optional<dcp::Effect> _effect;
-       boost::optional<dcp::Colour> _effect_colour;
-       /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */
-       double _line_spacing;
-       boost::optional<ContentTime> _fade_in;
-       boost::optional<ContentTime> _fade_out;
-       int _outline_width;
-};
-
-#endif
diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc
deleted file mode 100644 (file)
index 32cae6a..0000000
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
-    Copyright (C) 2013-2017 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 "subtitle_decoder.h"
-#include "subtitle_content.h"
-#include "util.h"
-#include "log.h"
-#include "compose.hpp"
-#include <sub/subtitle.h>
-#include <boost/shared_ptr.hpp>
-#include <boost/foreach.hpp>
-#include <boost/algorithm/string.hpp>
-#include <iostream>
-
-using std::list;
-using std::cout;
-using std::string;
-using std::min;
-using boost::shared_ptr;
-using boost::optional;
-using boost::function;
-
-SubtitleDecoder::SubtitleDecoder (
-       Decoder* parent,
-       shared_ptr<const SubtitleContent> c,
-       shared_ptr<Log> log,
-       ContentTime first
-       )
-       : DecoderPart (parent, log)
-       , _content (c)
-       , _position (first)
-{
-
-}
-
-/** Called by subclasses when an image subtitle is starting.
- *  @param from From time of the subtitle.
- *  @param image Subtitle image.
- *  @param rect Area expressed as a fraction of the video frame that this subtitle
- *  is for (e.g. a width of 0.5 means the width of the subtitle is half the width
- *  of the video frame)
- */
-void
-SubtitleDecoder::emit_image_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
-{
-       ImageStart (ContentImageSubtitle (from, image, rect));
-       _position = from;
-}
-
-void
-SubtitleDecoder::emit_text_start (ContentTime from, list<dcp::SubtitleString> s)
-{
-       BOOST_FOREACH (dcp::SubtitleString& i, s) {
-               /* We must escape < and > in strings, otherwise they might confuse our subtitle
-                  renderer (which uses some HTML-esque markup to do bold/italic etc.)
-               */
-               string t = i.text ();
-               boost::algorithm::replace_all (t, "<", "&lt;");
-               boost::algorithm::replace_all (t, ">", "&gt;");
-               i.set_text (t);
-
-               /* Set any forced appearance */
-               if (content()->colour()) {
-                       i.set_colour (*content()->colour());
-               }
-               if (content()->effect_colour()) {
-                       i.set_effect_colour (*content()->effect_colour());
-               }
-               if (content()->effect()) {
-                       i.set_effect (*content()->effect());
-               }
-               if (content()->fade_in()) {
-                       i.set_fade_up_time (dcp::Time(content()->fade_in()->seconds(), 1000));
-               }
-               if (content()->fade_out()) {
-                       i.set_fade_down_time (dcp::Time(content()->fade_out()->seconds(), 1000));
-               }
-       }
-
-       TextStart (ContentTextSubtitle (from, s));
-       _position = from;
-}
-
-void
-SubtitleDecoder::emit_text_start (ContentTime from, sub::Subtitle const & subtitle)
-{
-       /* See if our next subtitle needs to be vertically placed on screen by us */
-       bool needs_placement = false;
-       optional<int> bottom_line;
-       BOOST_FOREACH (sub::Line i, subtitle.lines) {
-               if (!i.vertical_position.reference || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) {
-                       needs_placement = true;
-                       DCPOMATIC_ASSERT (i.vertical_position.line);
-                       if (!bottom_line || bottom_line.get() < i.vertical_position.line.get()) {
-                               bottom_line = i.vertical_position.line.get();
-                       }
-               }
-       }
-
-       /* Find the lowest proportional position */
-       optional<float> lowest_proportional;
-       BOOST_FOREACH (sub::Line i, subtitle.lines) {
-               if (i.vertical_position.proportional) {
-                       if (!lowest_proportional) {
-                               lowest_proportional = i.vertical_position.proportional;
-                       } else {
-                               lowest_proportional = min (lowest_proportional.get(), i.vertical_position.proportional.get());
-                       }
-               }
-       }
-
-       list<dcp::SubtitleString> out;
-       BOOST_FOREACH (sub::Line i, subtitle.lines) {
-               BOOST_FOREACH (sub::Block j, i.blocks) {
-
-                       if (!j.font_size.specified()) {
-                               /* Fallback default font size if no other has been specified */
-                               j.font_size.set_points (48);
-                       }
-
-                       float v_position;
-                       dcp::VAlign v_align;
-                       if (needs_placement) {
-                               DCPOMATIC_ASSERT (i.vertical_position.line);
-                               /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom
-                                  of the screen a bit to a pleasing degree.
-                               */
-                               v_position = 1.015 -
-                                       (1 + bottom_line.get() - i.vertical_position.line.get())
-                                       * 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11);
-
-                               v_align = dcp::VALIGN_TOP;
-                       } else {
-                               DCPOMATIC_ASSERT (i.vertical_position.proportional);
-                               DCPOMATIC_ASSERT (i.vertical_position.reference);
-                               v_position = i.vertical_position.proportional.get();
-
-                               if (lowest_proportional) {
-                                       /* Adjust line spacing */
-                                       v_position = ((v_position - lowest_proportional.get()) * content()->line_spacing()) + lowest_proportional.get();
-                               }
-
-                               switch (i.vertical_position.reference.get()) {
-                               case sub::TOP_OF_SCREEN:
-                                       v_align = dcp::VALIGN_TOP;
-                                       break;
-                               case sub::VERTICAL_CENTRE_OF_SCREEN:
-                                       v_align = dcp::VALIGN_CENTER;
-                                       break;
-                               case sub::BOTTOM_OF_SCREEN:
-                                       v_align = dcp::VALIGN_BOTTOM;
-                                       break;
-                               default:
-                                       v_align = dcp::VALIGN_TOP;
-                                       break;
-                               }
-                       }
-
-                       dcp::HAlign h_align;
-                       switch (i.horizontal_position.reference) {
-                       case sub::LEFT_OF_SCREEN:
-                               h_align = dcp::HALIGN_LEFT;
-                               break;
-                       case sub::HORIZONTAL_CENTRE_OF_SCREEN:
-                               h_align = dcp::HALIGN_CENTER;
-                               break;
-                       case sub::RIGHT_OF_SCREEN:
-                               h_align = dcp::HALIGN_RIGHT;
-                               break;
-                       default:
-                               h_align = dcp::HALIGN_CENTER;
-                               break;
-                       }
-
-                       /* The idea here (rightly or wrongly) is that we set the appearance based on the
-                          values in the libsub objects, and these are overridden with values from the
-                          content by the other emit_text_start() above.
-                       */
-
-                       out.push_back (
-                               dcp::SubtitleString (
-                                       string(TEXT_FONT_ID),
-                                       j.italic,
-                                       j.bold,
-                                       j.underline,
-                                       j.colour.dcp(),
-                                       j.font_size.points (72 * 11),
-                                       1.0,
-                                       dcp::Time (from.seconds(), 1000),
-                                       /* XXX: hmm; this is a bit ugly (we don't know the to time yet) */
-                                       dcp::Time (),
-                                       i.horizontal_position.proportional,
-                                       h_align,
-                                       v_position,
-                                       v_align,
-                                       dcp::DIRECTION_LTR,
-                                       j.text,
-                                       dcp::NONE,
-                                       j.effect_colour.get_value_or(sub::Colour(0, 0, 0)).dcp(),
-                                       /* Hack: we should use subtitle.fade_up and subtitle.fade_down here
-                                          but the times of these often don't have a frame rate associated
-                                          with them so the sub::Time won't convert them to milliseconds without
-                                          throwing an exception.  Since only DCP subs fill those in (and we don't
-                                          use libsub for DCP subs) we can cheat by just putting 0 in here.
-                                       */
-                                       dcp::Time (),
-                                       dcp::Time ()
-                                       )
-                               );
-               }
-       }
-
-       emit_text_start (from, out);
-}
-
-void
-SubtitleDecoder::emit_stop (ContentTime to)
-{
-       Stop (to);
-}
-
-void
-SubtitleDecoder::emit_text (ContentTimePeriod period, list<dcp::SubtitleString> s)
-{
-       emit_text_start (period.from, s);
-       emit_stop (period.to);
-}
-
-void
-SubtitleDecoder::emit_text (ContentTimePeriod period, sub::Subtitle const & s)
-{
-       emit_text_start (period.from, s);
-       emit_stop (period.to);
-}
-
-void
-SubtitleDecoder::seek ()
-{
-       _position = ContentTime ();
-}
diff --git a/src/lib/subtitle_decoder.h b/src/lib/subtitle_decoder.h
deleted file mode 100644 (file)
index c1f171b..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
-    Copyright (C) 2013-2017 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/>.
-
-*/
-
-#ifndef DCPOMATIC_SUBTITLE_DECODER_H
-#define DCPOMATIC_SUBTITLE_DECODER_H
-
-#include "decoder.h"
-#include "rect.h"
-#include "types.h"
-#include "content_subtitle.h"
-#include "decoder_part.h"
-#include <dcp/subtitle_string.h>
-#include <boost/signals2.hpp>
-
-namespace sub {
-       class Subtitle;
-}
-
-class Image;
-
-class SubtitleDecoder : public DecoderPart
-{
-public:
-       SubtitleDecoder (
-               Decoder* parent,
-               boost::shared_ptr<const SubtitleContent>,
-               boost::shared_ptr<Log> log,
-               ContentTime first
-               );
-
-       ContentTime position () const {
-               return _position;
-       }
-
-       void emit_image_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
-       void emit_text_start (ContentTime from, std::list<dcp::SubtitleString> s);
-       void emit_text_start (ContentTime from, sub::Subtitle const & subtitle);
-       void emit_text (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
-       void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle);
-       void emit_stop (ContentTime to);
-
-       void seek ();
-
-       boost::shared_ptr<const SubtitleContent> content () const {
-               return _content;
-       }
-
-       boost::signals2::signal<void (ContentImageSubtitle)> ImageStart;
-       boost::signals2::signal<void (ContentTextSubtitle)> TextStart;
-       boost::signals2::signal<void (ContentTime)> Stop;
-
-private:
-       boost::shared_ptr<const SubtitleContent> _content;
-       ContentTime _position;
-};
-
-#endif
diff --git a/src/lib/text_content.cc b/src/lib/text_content.cc
new file mode 100644 (file)
index 0000000..9eae635
--- /dev/null
@@ -0,0 +1,515 @@
+/*
+    Copyright (C) 2013-2018 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 "text_content.h"
+#include "util.h"
+#include "exceptions.h"
+#include "font.h"
+#include "content.h"
+#include <dcp/raw_convert.h>
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::vector;
+using std::cout;
+using std::list;
+using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
+using boost::optional;
+using dcp::raw_convert;
+
+int const TextContentProperty::X_OFFSET = 500;
+int const TextContentProperty::Y_OFFSET = 501;
+int const TextContentProperty::X_SCALE = 502;
+int const TextContentProperty::Y_SCALE = 503;
+int const TextContentProperty::USE = 504;
+int const TextContentProperty::BURN = 505;
+int const TextContentProperty::LANGUAGE = 506;
+int const TextContentProperty::FONTS = 507;
+int const TextContentProperty::COLOUR = 508;
+int const TextContentProperty::EFFECT = 509;
+int const TextContentProperty::EFFECT_COLOUR = 510;
+int const TextContentProperty::LINE_SPACING = 511;
+int const TextContentProperty::FADE_IN = 512;
+int const TextContentProperty::FADE_OUT = 513;
+int const TextContentProperty::OUTLINE_WIDTH = 514;
+
+TextContent::TextContent (Content* parent)
+       : ContentPart (parent)
+       , _use (false)
+       , _burn (false)
+       , _x_offset (0)
+       , _y_offset (0)
+       , _x_scale (1)
+       , _y_scale (1)
+       , _line_spacing (1)
+       , _outline_width (2)
+{
+
+}
+
+shared_ptr<TextContent>
+TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version)
+{
+       if (version < 34) {
+               /* With old metadata FFmpeg content has the subtitle-related tags even with no
+                  subtitle streams, so check for that.
+               */
+               if (node->string_child("Type") == "FFmpeg" && node->node_children("SubtitleStream").empty()) {
+                       return shared_ptr<TextContent> ();
+               }
+
+               /* Otherwise we can drop through to the newer logic */
+       }
+
+       if (!node->optional_number_child<double>("SubtitleXOffset") && !node->optional_number_child<double>("SubtitleOffset")) {
+               return shared_ptr<TextContent> ();
+       }
+
+       return shared_ptr<TextContent> (new TextContent (parent, node, version));
+}
+
+TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version)
+       : ContentPart (parent)
+       , _use (false)
+       , _burn (false)
+       , _x_offset (0)
+       , _y_offset (0)
+       , _x_scale (1)
+       , _y_scale (1)
+       , _line_spacing (node->optional_number_child<double>("LineSpacing").get_value_or (1))
+       , _outline_width (node->optional_number_child<int>("OutlineWidth").get_value_or (2))
+{
+       if (version >= 32) {
+               _use = node->bool_child ("UseSubtitles");
+               _burn = node->bool_child ("BurnSubtitles");
+       }
+
+       if (version >= 7) {
+               _x_offset = node->number_child<double> ("SubtitleXOffset");
+               _y_offset = node->number_child<double> ("SubtitleYOffset");
+       } else {
+               _y_offset = node->number_child<double> ("SubtitleOffset");
+       }
+
+       if (node->optional_bool_child("Outline").get_value_or(false)) {
+               _effect = dcp::BORDER;
+       } else if (node->optional_bool_child("Shadow").get_value_or(false)) {
+               _effect = dcp::SHADOW;
+       } else {
+               _effect = dcp::NONE;
+       }
+
+       optional<string> effect = node->optional_string_child("Effect");
+       if (effect) {
+               if (*effect == "none") {
+                       _effect = dcp::NONE;
+               } else if (*effect == "outline") {
+                       _effect = dcp::BORDER;
+               } else if (*effect == "shadow") {
+                       _effect = dcp::SHADOW;
+               }
+       }
+
+       if (version >= 10) {
+               _x_scale = node->number_child<double> ("SubtitleXScale");
+               _y_scale = node->number_child<double> ("SubtitleYScale");
+       } else {
+               _x_scale = _y_scale = node->number_child<double> ("SubtitleScale");
+       }
+
+       optional<int> r = node->optional_number_child<int>("Red");
+       optional<int> g = node->optional_number_child<int>("Green");
+       optional<int> b = node->optional_number_child<int>("Blue");
+       if (r && g && b) {
+               _colour = dcp::Colour (*r, *g, *b);
+       }
+
+       if (version >= 36) {
+               optional<int> er = node->optional_number_child<int>("EffectRed");
+               optional<int> eg = node->optional_number_child<int>("EffectGreen");
+               optional<int> eb = node->optional_number_child<int>("EffectBlue");
+               if (er && eg && eb) {
+                       _effect_colour = dcp::Colour (*er, *eg, *eb);
+               }
+       } else {
+               _effect_colour = dcp::Colour (
+                       node->optional_number_child<int>("OutlineRed").get_value_or(255),
+                       node->optional_number_child<int>("OutlineGreen").get_value_or(255),
+                       node->optional_number_child<int>("OutlineBlue").get_value_or(255)
+                       );
+       }
+
+       optional<Frame> fi = node->optional_number_child<Frame>("SubtitleFadeIn");
+       if (fi) {
+               _fade_in = ContentTime (*fi);
+       }
+       optional<Frame> fo = node->optional_number_child<Frame>("SubtitleFadeOut");
+       if (fo) {
+               _fade_out = ContentTime (*fo);
+       }
+
+       _language = node->optional_string_child ("SubtitleLanguage").get_value_or ("");
+
+       list<cxml::NodePtr> fonts = node->node_children ("Font");
+       for (list<cxml::NodePtr>::const_iterator i = fonts.begin(); i != fonts.end(); ++i) {
+               _fonts.push_back (shared_ptr<Font> (new Font (*i)));
+       }
+
+       connect_to_fonts ();
+}
+
+TextContent::TextContent (Content* parent, vector<shared_ptr<Content> > c)
+       : ContentPart (parent)
+{
+       shared_ptr<TextContent> ref = c[0]->subtitle;
+       DCPOMATIC_ASSERT (ref);
+       list<shared_ptr<Font> > ref_fonts = ref->fonts ();
+
+       for (size_t i = 1; i < c.size(); ++i) {
+
+               if (c[i]->subtitle->use() != ref->use()) {
+                       throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
+               }
+
+               if (c[i]->subtitle->burn() != ref->burn()) {
+                       throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
+               }
+
+               if (c[i]->subtitle->x_offset() != ref->x_offset()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle X offset."));
+               }
+
+               if (c[i]->subtitle->y_offset() != ref->y_offset()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
+               }
+
+               if (c[i]->subtitle->x_scale() != ref->x_scale()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle X scale."));
+               }
+
+               if (c[i]->subtitle->y_scale() != ref->y_scale()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
+               }
+
+               if (c[i]->subtitle->line_spacing() != ref->line_spacing()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
+               }
+
+               if ((c[i]->subtitle->fade_in() != ref->fade_in()) || (c[i]->subtitle->fade_out() != ref->fade_out())) {
+                       throw JoinError (_("Content to be joined must have the same subtitle fades."));
+               }
+
+               if ((c[i]->subtitle->outline_width() != ref->outline_width())) {
+                       throw JoinError (_("Content to be joined must have the same outline width."));
+               }
+
+               list<shared_ptr<Font> > fonts = c[i]->subtitle->fonts ();
+               if (fonts.size() != ref_fonts.size()) {
+                       throw JoinError (_("Content to be joined must use the same fonts."));
+               }
+
+               list<shared_ptr<Font> >::const_iterator j = ref_fonts.begin ();
+               list<shared_ptr<Font> >::const_iterator k = fonts.begin ();
+
+               while (j != ref_fonts.end ()) {
+                       if (**j != **k) {
+                               throw JoinError (_("Content to be joined must use the same fonts."));
+                       }
+                       ++j;
+                       ++k;
+               }
+       }
+
+       _use = ref->use ();
+       _burn = ref->burn ();
+       _x_offset = ref->x_offset ();
+       _y_offset = ref->y_offset ();
+       _x_scale = ref->x_scale ();
+       _y_scale = ref->y_scale ();
+       _language = ref->language ();
+       _fonts = ref_fonts;
+       _line_spacing = ref->line_spacing ();
+       _fade_in = ref->fade_in ();
+       _fade_out = ref->fade_out ();
+       _outline_width = ref->outline_width ();
+
+       connect_to_fonts ();
+}
+
+/** _mutex must not be held on entry */
+void
+TextContent::as_xml (xmlpp::Node* root) const
+{
+       boost::mutex::scoped_lock lm (_mutex);
+
+       root->add_child("UseSubtitles")->add_child_text (_use ? "1" : "0");
+       root->add_child("BurnSubtitles")->add_child_text (_burn ? "1" : "0");
+       root->add_child("SubtitleXOffset")->add_child_text (raw_convert<string> (_x_offset));
+       root->add_child("SubtitleYOffset")->add_child_text (raw_convert<string> (_y_offset));
+       root->add_child("SubtitleXScale")->add_child_text (raw_convert<string> (_x_scale));
+       root->add_child("SubtitleYScale")->add_child_text (raw_convert<string> (_y_scale));
+       root->add_child("SubtitleLanguage")->add_child_text (_language);
+       if (_colour) {
+               root->add_child("Red")->add_child_text (raw_convert<string> (_colour->r));
+               root->add_child("Green")->add_child_text (raw_convert<string> (_colour->g));
+               root->add_child("Blue")->add_child_text (raw_convert<string> (_colour->b));
+       }
+       if (_effect) {
+               switch (*_effect) {
+               case dcp::NONE:
+                       root->add_child("Effect")->add_child_text("none");
+                       break;
+               case dcp::BORDER:
+                       root->add_child("Effect")->add_child_text("outline");
+                       break;
+               case dcp::SHADOW:
+                       root->add_child("Effect")->add_child_text("shadow");
+                       break;
+               }
+       }
+       if (_effect_colour) {
+               root->add_child("EffectRed")->add_child_text (raw_convert<string> (_effect_colour->r));
+               root->add_child("EffectGreen")->add_child_text (raw_convert<string> (_effect_colour->g));
+               root->add_child("EffectBlue")->add_child_text (raw_convert<string> (_effect_colour->b));
+       }
+       root->add_child("LineSpacing")->add_child_text (raw_convert<string> (_line_spacing));
+       if (_fade_in) {
+               root->add_child("SubtitleFadeIn")->add_child_text (raw_convert<string> (_fade_in->get()));
+       }
+       if (_fade_out) {
+               root->add_child("SubtitleFadeOut")->add_child_text (raw_convert<string> (_fade_out->get()));
+       }
+       root->add_child("OutlineWidth")->add_child_text (raw_convert<string> (_outline_width));
+
+       for (list<shared_ptr<Font> >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) {
+               (*i)->as_xml (root->add_child("Font"));
+       }
+}
+
+string
+TextContent::identifier () const
+{
+       string s = raw_convert<string> (x_scale())
+               + "_" + raw_convert<string> (y_scale())
+               + "_" + raw_convert<string> (x_offset())
+               + "_" + raw_convert<string> (y_offset())
+               + "_" + raw_convert<string> (line_spacing())
+               + "_" + raw_convert<string> (fade_in().get_value_or(ContentTime()).get())
+               + "_" + raw_convert<string> (fade_out().get_value_or(ContentTime()).get())
+               + "_" + raw_convert<string> (outline_width())
+               + "_" + raw_convert<string> (colour().get_value_or(dcp::Colour(255, 255, 255)).to_argb_string())
+               + "_" + raw_convert<string> (dcp::effect_to_string(effect().get_value_or(dcp::NONE)))
+               + "_" + raw_convert<string> (effect_colour().get_value_or(dcp::Colour(0, 0, 0)).to_argb_string());
+
+       /* XXX: I suppose really _fonts shouldn't be in here, since not all
+          types of subtitle content involve fonts.
+       */
+       BOOST_FOREACH (shared_ptr<Font> f, _fonts) {
+               for (int i = 0; i < FontFiles::VARIANTS; ++i) {
+                       s += "_" + f->file(static_cast<FontFiles::Variant>(i)).get_value_or("Default").string();
+               }
+       }
+
+       /* The language is for metadata only, and doesn't affect
+          how this content looks.
+       */
+
+       return s;
+}
+
+void
+TextContent::add_font (shared_ptr<Font> font)
+{
+       _fonts.push_back (font);
+       connect_to_fonts ();
+}
+
+void
+TextContent::connect_to_fonts ()
+{
+       BOOST_FOREACH (boost::signals2::connection& i, _font_connections) {
+               i.disconnect ();
+       }
+
+       _font_connections.clear ();
+
+       BOOST_FOREACH (shared_ptr<Font> i, _fonts) {
+               _font_connections.push_back (i->Changed.connect (boost::bind (&TextContent::font_changed, this)));
+       }
+}
+
+void
+TextContent::font_changed ()
+{
+       _parent->signal_changed (TextContentProperty::FONTS);
+}
+
+void
+TextContent::set_colour (dcp::Colour colour)
+{
+       maybe_set (_colour, colour, TextContentProperty::COLOUR);
+}
+
+void
+TextContent::unset_colour ()
+{
+       maybe_set (_colour, optional<dcp::Colour>(), TextContentProperty::COLOUR);
+}
+
+void
+TextContent::set_effect (dcp::Effect e)
+{
+       maybe_set (_effect, e, TextContentProperty::EFFECT);
+}
+
+void
+TextContent::unset_effect ()
+{
+       maybe_set (_effect, optional<dcp::Effect>(), TextContentProperty::EFFECT);
+}
+
+void
+TextContent::set_effect_colour (dcp::Colour colour)
+{
+       maybe_set (_effect_colour, colour, TextContentProperty::EFFECT_COLOUR);
+}
+
+void
+TextContent::unset_effect_colour ()
+{
+       maybe_set (_effect_colour, optional<dcp::Colour>(), TextContentProperty::EFFECT_COLOUR);
+}
+
+void
+TextContent::set_use (bool u)
+{
+       maybe_set (_use, u, TextContentProperty::USE);
+}
+
+void
+TextContent::set_burn (bool b)
+{
+       maybe_set (_burn, b, TextContentProperty::BURN);
+}
+
+void
+TextContent::set_x_offset (double o)
+{
+       maybe_set (_x_offset, o, TextContentProperty::X_OFFSET);
+}
+
+void
+TextContent::set_y_offset (double o)
+{
+       maybe_set (_y_offset, o, TextContentProperty::Y_OFFSET);
+}
+
+void
+TextContent::set_x_scale (double s)
+{
+       maybe_set (_x_scale, s, TextContentProperty::X_SCALE);
+}
+
+void
+TextContent::set_y_scale (double s)
+{
+       maybe_set (_y_scale, s, TextContentProperty::Y_SCALE);
+}
+
+void
+TextContent::set_language (string language)
+{
+       maybe_set (_language, language, TextContentProperty::LANGUAGE);
+}
+
+void
+TextContent::set_line_spacing (double s)
+{
+       maybe_set (_line_spacing, s, TextContentProperty::LINE_SPACING);
+}
+
+void
+TextContent::set_fade_in (ContentTime t)
+{
+       maybe_set (_fade_in, t, TextContentProperty::FADE_IN);
+}
+
+void
+TextContent::unset_fade_in ()
+{
+       maybe_set (_fade_in, optional<ContentTime>(), TextContentProperty::FADE_IN);
+}
+
+void
+TextContent::set_fade_out (ContentTime t)
+{
+       maybe_set (_fade_out, t, TextContentProperty::FADE_OUT);
+}
+
+void
+TextContent::unset_fade_out ()
+{
+       maybe_set (_fade_out, optional<ContentTime>(), TextContentProperty::FADE_OUT);
+}
+
+void
+TextContent::set_outline_width (int w)
+{
+       maybe_set (_outline_width, w, TextContentProperty::OUTLINE_WIDTH);
+}
+
+void
+TextContent::take_settings_from (shared_ptr<const TextContent> c)
+{
+       set_use (c->_use);
+       set_burn (c->_burn);
+       set_x_offset (c->_x_offset);
+       set_y_offset (c->_y_offset);
+       set_x_scale (c->_x_scale);
+       set_y_scale (c->_y_scale);
+       maybe_set (_fonts, c->_fonts, TextContentProperty::FONTS);
+       if (c->_colour) {
+               set_colour (*c->_colour);
+       } else {
+               unset_colour ();
+       }
+       if (c->_effect) {
+               set_effect (*c->_effect);
+       }
+       if (c->_effect_colour) {
+               set_effect_colour (*c->_effect_colour);
+       } else {
+               unset_effect_colour ();
+       }
+       set_line_spacing (c->_line_spacing);
+       if (c->_fade_in) {
+               set_fade_in (*c->_fade_in);
+       }
+       if (c->_fade_out) {
+               set_fade_out (*c->_fade_out);
+       }
+       set_outline_width (c->_outline_width);
+}
diff --git a/src/lib/text_content.h b/src/lib/text_content.h
new file mode 100644 (file)
index 0000000..9411843
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+    Copyright (C) 2013-2018 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/>.
+
+*/
+
+#ifndef DCPOMATIC_SUBTITLE_CONTENT_H
+#define DCPOMATIC_SUBTITLE_CONTENT_H
+
+#include "content_part.h"
+#include <libcxml/cxml.h>
+#include <dcp/types.h>
+#include <boost/signals2.hpp>
+
+class Font;
+
+class TextContentProperty
+{
+public:
+       static int const X_OFFSET;
+       static int const Y_OFFSET;
+       static int const X_SCALE;
+       static int const Y_SCALE;
+       static int const USE;
+       static int const BURN;
+       static int const LANGUAGE;
+       static int const FONTS;
+       static int const COLOUR;
+       static int const EFFECT;
+       static int const EFFECT_COLOUR;
+       static int const LINE_SPACING;
+       static int const FADE_IN;
+       static int const FADE_OUT;
+       static int const OUTLINE_WIDTH;
+};
+
+/** @class TextContent
+ *  @brief Description of how some subtitle content should be presented.
+ *
+ *  There are `image' subtitles (bitmaps) and `text' subtitles (plain text),
+ *  and not all of the settings in this class correspond to both types.
+ */
+class TextContent : public ContentPart
+{
+public:
+       explicit TextContent (Content* parent);
+       TextContent (Content* parent, std::vector<boost::shared_ptr<Content> >);
+
+       void as_xml (xmlpp::Node *) const;
+       std::string identifier () const;
+       void take_settings_from (boost::shared_ptr<const TextContent> c);
+
+       void add_font (boost::shared_ptr<Font> font);
+
+       void set_use (bool);
+       void set_burn (bool);
+       void set_x_offset (double);
+       void set_y_offset (double);
+       void set_x_scale (double);
+       void set_y_scale (double);
+       void set_language (std::string language);
+       void set_colour (dcp::Colour);
+       void unset_colour ();
+       void set_effect (dcp::Effect);
+       void unset_effect ();
+       void set_effect_colour (dcp::Colour);
+       void unset_effect_colour ();
+       void set_line_spacing (double s);
+       void set_fade_in (ContentTime);
+       void unset_fade_in ();
+       void set_fade_out (ContentTime);
+       void set_outline_width (int);
+       void unset_fade_out ();
+
+       bool use () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _use;
+       }
+
+       bool burn () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _burn;
+       }
+
+       double x_offset () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _x_offset;
+       }
+
+       double y_offset () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _y_offset;
+       }
+
+       double x_scale () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _x_scale;
+       }
+
+       double y_scale () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _y_scale;
+       }
+
+       std::list<boost::shared_ptr<Font> > fonts () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _fonts;
+       }
+
+       std::string language () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _language;
+       }
+
+       boost::optional<dcp::Colour> colour () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _colour;
+       }
+
+       boost::optional<dcp::Effect> effect () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _effect;
+       }
+
+       boost::optional<dcp::Colour> effect_colour () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _effect_colour;
+       }
+
+       double line_spacing () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _line_spacing;
+       }
+
+       boost::optional<ContentTime> fade_in () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _fade_in;
+       }
+
+       boost::optional<ContentTime> fade_out () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _fade_out;
+       }
+
+       int outline_width () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _outline_width;
+       }
+
+       static boost::shared_ptr<TextContent> from_xml (Content* parent, cxml::ConstNodePtr, int version);
+
+protected:
+       /** subtitle language (e.g. "German") or empty if it is not known */
+       std::string _language;
+
+private:
+       friend struct ffmpeg_pts_offset_test;
+
+       TextContent (Content* parent, cxml::ConstNodePtr, int version);
+       void font_changed ();
+       void connect_to_fonts ();
+
+       std::list<boost::signals2::connection> _font_connections;
+
+       bool _use;
+       bool _burn;
+       /** x offset for placing subtitles, as a proportion of the container width;
+        * +ve is further right, -ve is further left.
+        */
+       double _x_offset;
+       /** y offset for placing subtitles, as a proportion of the container height;
+        *  +ve is further down the frame, -ve is further up.
+        */
+       double _y_offset;
+       /** x scale factor to apply to subtitles */
+       double _x_scale;
+       /** y scale factor to apply to subtitles */
+       double _y_scale;
+       std::list<boost::shared_ptr<Font> > _fonts;
+       boost::optional<dcp::Colour> _colour;
+       boost::optional<dcp::Effect> _effect;
+       boost::optional<dcp::Colour> _effect_colour;
+       /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */
+       double _line_spacing;
+       boost::optional<ContentTime> _fade_in;
+       boost::optional<ContentTime> _fade_out;
+       int _outline_width;
+};
+
+#endif
diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc
new file mode 100644 (file)
index 0000000..56a7e1e
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+    Copyright (C) 2013-2017 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 "text_decoder.h"
+#include "text_content.h"
+#include "util.h"
+#include "log.h"
+#include "compose.hpp"
+#include <sub/subtitle.h>
+#include <boost/shared_ptr.hpp>
+#include <boost/foreach.hpp>
+#include <boost/algorithm/string.hpp>
+#include <iostream>
+
+using std::list;
+using std::cout;
+using std::string;
+using std::min;
+using boost::shared_ptr;
+using boost::optional;
+using boost::function;
+
+TextDecoder::TextDecoder (
+       Decoder* parent,
+       shared_ptr<const TextContent> c,
+       shared_ptr<Log> log,
+       ContentTime first
+       )
+       : DecoderPart (parent, log)
+       , _content (c)
+       , _position (first)
+{
+
+}
+
+/** Called by subclasses when an image subtitle is starting.
+ *  @param from From time of the subtitle.
+ *  @param image Subtitle image.
+ *  @param rect Area expressed as a fraction of the video frame that this subtitle
+ *  is for (e.g. a width of 0.5 means the width of the subtitle is half the width
+ *  of the video frame)
+ */
+void
+TextDecoder::emit_image_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
+{
+       ImageStart (ContentImageSubtitle (from, image, rect));
+       _position = from;
+}
+
+void
+TextDecoder::emit_text_start (ContentTime from, list<dcp::SubtitleString> s)
+{
+       BOOST_FOREACH (dcp::SubtitleString& i, s) {
+               /* We must escape < and > in strings, otherwise they might confuse our subtitle
+                  renderer (which uses some HTML-esque markup to do bold/italic etc.)
+               */
+               string t = i.text ();
+               boost::algorithm::replace_all (t, "<", "&lt;");
+               boost::algorithm::replace_all (t, ">", "&gt;");
+               i.set_text (t);
+
+               /* Set any forced appearance */
+               if (content()->colour()) {
+                       i.set_colour (*content()->colour());
+               }
+               if (content()->effect_colour()) {
+                       i.set_effect_colour (*content()->effect_colour());
+               }
+               if (content()->effect()) {
+                       i.set_effect (*content()->effect());
+               }
+               if (content()->fade_in()) {
+                       i.set_fade_up_time (dcp::Time(content()->fade_in()->seconds(), 1000));
+               }
+               if (content()->fade_out()) {
+                       i.set_fade_down_time (dcp::Time(content()->fade_out()->seconds(), 1000));
+               }
+       }
+
+       TextStart (ContentTextSubtitle (from, s));
+       _position = from;
+}
+
+void
+TextDecoder::emit_text_start (ContentTime from, sub::Subtitle const & subtitle)
+{
+       /* See if our next subtitle needs to be vertically placed on screen by us */
+       bool needs_placement = false;
+       optional<int> bottom_line;
+       BOOST_FOREACH (sub::Line i, subtitle.lines) {
+               if (!i.vertical_position.reference || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) {
+                       needs_placement = true;
+                       DCPOMATIC_ASSERT (i.vertical_position.line);
+                       if (!bottom_line || bottom_line.get() < i.vertical_position.line.get()) {
+                               bottom_line = i.vertical_position.line.get();
+                       }
+               }
+       }
+
+       /* Find the lowest proportional position */
+       optional<float> lowest_proportional;
+       BOOST_FOREACH (sub::Line i, subtitle.lines) {
+               if (i.vertical_position.proportional) {
+                       if (!lowest_proportional) {
+                               lowest_proportional = i.vertical_position.proportional;
+                       } else {
+                               lowest_proportional = min (lowest_proportional.get(), i.vertical_position.proportional.get());
+                       }
+               }
+       }
+
+       list<dcp::SubtitleString> out;
+       BOOST_FOREACH (sub::Line i, subtitle.lines) {
+               BOOST_FOREACH (sub::Block j, i.blocks) {
+
+                       if (!j.font_size.specified()) {
+                               /* Fallback default font size if no other has been specified */
+                               j.font_size.set_points (48);
+                       }
+
+                       float v_position;
+                       dcp::VAlign v_align;
+                       if (needs_placement) {
+                               DCPOMATIC_ASSERT (i.vertical_position.line);
+                               /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom
+                                  of the screen a bit to a pleasing degree.
+                               */
+                               v_position = 1.015 -
+                                       (1 + bottom_line.get() - i.vertical_position.line.get())
+                                       * 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11);
+
+                               v_align = dcp::VALIGN_TOP;
+                       } else {
+                               DCPOMATIC_ASSERT (i.vertical_position.proportional);
+                               DCPOMATIC_ASSERT (i.vertical_position.reference);
+                               v_position = i.vertical_position.proportional.get();
+
+                               if (lowest_proportional) {
+                                       /* Adjust line spacing */
+                                       v_position = ((v_position - lowest_proportional.get()) * content()->line_spacing()) + lowest_proportional.get();
+                               }
+
+                               switch (i.vertical_position.reference.get()) {
+                               case sub::TOP_OF_SCREEN:
+                                       v_align = dcp::VALIGN_TOP;
+                                       break;
+                               case sub::VERTICAL_CENTRE_OF_SCREEN:
+                                       v_align = dcp::VALIGN_CENTER;
+                                       break;
+                               case sub::BOTTOM_OF_SCREEN:
+                                       v_align = dcp::VALIGN_BOTTOM;
+                                       break;
+                               default:
+                                       v_align = dcp::VALIGN_TOP;
+                                       break;
+                               }
+                       }
+
+                       dcp::HAlign h_align;
+                       switch (i.horizontal_position.reference) {
+                       case sub::LEFT_OF_SCREEN:
+                               h_align = dcp::HALIGN_LEFT;
+                               break;
+                       case sub::HORIZONTAL_CENTRE_OF_SCREEN:
+                               h_align = dcp::HALIGN_CENTER;
+                               break;
+                       case sub::RIGHT_OF_SCREEN:
+                               h_align = dcp::HALIGN_RIGHT;
+                               break;
+                       default:
+                               h_align = dcp::HALIGN_CENTER;
+                               break;
+                       }
+
+                       /* The idea here (rightly or wrongly) is that we set the appearance based on the
+                          values in the libsub objects, and these are overridden with values from the
+                          content by the other emit_text_start() above.
+                       */
+
+                       out.push_back (
+                               dcp::SubtitleString (
+                                       string(TEXT_FONT_ID),
+                                       j.italic,
+                                       j.bold,
+                                       j.underline,
+                                       j.colour.dcp(),
+                                       j.font_size.points (72 * 11),
+                                       1.0,
+                                       dcp::Time (from.seconds(), 1000),
+                                       /* XXX: hmm; this is a bit ugly (we don't know the to time yet) */
+                                       dcp::Time (),
+                                       i.horizontal_position.proportional,
+                                       h_align,
+                                       v_position,
+                                       v_align,
+                                       dcp::DIRECTION_LTR,
+                                       j.text,
+                                       dcp::NONE,
+                                       j.effect_colour.get_value_or(sub::Colour(0, 0, 0)).dcp(),
+                                       /* Hack: we should use subtitle.fade_up and subtitle.fade_down here
+                                          but the times of these often don't have a frame rate associated
+                                          with them so the sub::Time won't convert them to milliseconds without
+                                          throwing an exception.  Since only DCP subs fill those in (and we don't
+                                          use libsub for DCP subs) we can cheat by just putting 0 in here.
+                                       */
+                                       dcp::Time (),
+                                       dcp::Time ()
+                                       )
+                               );
+               }
+       }
+
+       emit_text_start (from, out);
+}
+
+void
+TextDecoder::emit_stop (ContentTime to)
+{
+       Stop (to);
+}
+
+void
+TextDecoder::emit_text (ContentTimePeriod period, list<dcp::SubtitleString> s)
+{
+       emit_text_start (period.from, s);
+       emit_stop (period.to);
+}
+
+void
+TextDecoder::emit_text (ContentTimePeriod period, sub::Subtitle const & s)
+{
+       emit_text_start (period.from, s);
+       emit_stop (period.to);
+}
+
+void
+TextDecoder::seek ()
+{
+       _position = ContentTime ();
+}
diff --git a/src/lib/text_decoder.h b/src/lib/text_decoder.h
new file mode 100644 (file)
index 0000000..d9d351d
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+    Copyright (C) 2013-2017 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/>.
+
+*/
+
+#ifndef DCPOMATIC_SUBTITLE_DECODER_H
+#define DCPOMATIC_SUBTITLE_DECODER_H
+
+#include "decoder.h"
+#include "rect.h"
+#include "types.h"
+#include "content_subtitle.h"
+#include "decoder_part.h"
+#include <dcp/subtitle_string.h>
+#include <boost/signals2.hpp>
+
+namespace sub {
+       class Subtitle;
+}
+
+class Image;
+
+class TextDecoder : public DecoderPart
+{
+public:
+       TextDecoder (
+               Decoder* parent,
+               boost::shared_ptr<const TextContent>,
+               boost::shared_ptr<Log> log,
+               ContentTime first
+               );
+
+       ContentTime position () const {
+               return _position;
+       }
+
+       void emit_image_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
+       void emit_text_start (ContentTime from, std::list<dcp::SubtitleString> s);
+       void emit_text_start (ContentTime from, sub::Subtitle const & subtitle);
+       void emit_text (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
+       void emit_text (ContentTimePeriod period, sub::Subtitle const & subtitle);
+       void emit_stop (ContentTime to);
+
+       void seek ();
+
+       boost::shared_ptr<const TextContent> content () const {
+               return _content;
+       }
+
+       boost::signals2::signal<void (ContentImageSubtitle)> ImageStart;
+       boost::signals2::signal<void (ContentTextSubtitle)> TextStart;
+       boost::signals2::signal<void (ContentTime)> Stop;
+
+private:
+       boost::shared_ptr<const TextContent> _content;
+       ContentTime _position;
+};
+
+#endif
diff --git a/src/lib/text_file.cc b/src/lib/text_file.cc
new file mode 100644 (file)
index 0000000..b6a0757
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+    Copyright (C) 2014-2016 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 "text_file.h"
+#include "cross.h"
+#include "exceptions.h"
+#include "text_file_content.h"
+#include <sub/subrip_reader.h>
+#include <sub/ssa_reader.h>
+#include <sub/collect.h>
+#include <unicode/ucsdet.h>
+#include <unicode/ucnv.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::vector;
+using std::cout;
+using std::string;
+using boost::shared_ptr;
+using boost::scoped_array;
+using dcp::Data;
+
+TextFile::TextFile (shared_ptr<const TextFileContent> content)
+{
+       Data in (content->path (0));
+
+       UErrorCode status = U_ZERO_ERROR;
+       UCharsetDetector* detector = ucsdet_open (&status);
+       ucsdet_setText (detector, reinterpret_cast<const char *> (in.data().get()), in.size(), &status);
+
+       UCharsetMatch const * match = ucsdet_detect (detector, &status);
+       char const * in_charset = ucsdet_getName (match, &status);
+
+       UConverter* to_utf16 = ucnv_open (in_charset, &status);
+       /* This is a guess; I think we should be able to encode any input in 4 times its input size */
+       scoped_array<uint16_t> utf16 (new uint16_t[in.size() * 2]);
+       int const utf16_len = ucnv_toUChars (
+               to_utf16, reinterpret_cast<UChar*>(utf16.get()), in.size() * 2,
+               reinterpret_cast<const char *> (in.data().get()), in.size(),
+               &status
+               );
+
+       UConverter* to_utf8 = ucnv_open ("UTF-8", &status);
+       /* Another guess */
+       scoped_array<char> utf8 (new char[utf16_len * 2]);
+       ucnv_fromUChars (to_utf8, utf8.get(), utf16_len * 2, reinterpret_cast<UChar*>(utf16.get()), utf16_len, &status);
+
+       ucsdet_close (detector);
+       ucnv_close (to_utf16);
+       ucnv_close (to_utf8);
+
+       sub::Reader* reader = 0;
+
+       string ext = content->path(0).extension().string();
+       transform (ext.begin(), ext.end(), ext.begin(), ::tolower);
+
+       if (ext == ".srt") {
+               reader = new sub::SubripReader (utf8.get());
+       } else if (ext == ".ssa" || ext == ".ass") {
+               reader = new sub::SSAReader (utf8.get());
+       }
+
+       if (reader) {
+               _subtitles = sub::collect<vector<sub::Subtitle> > (reader->subtitles ());
+       }
+
+       delete reader;
+}
+
+ContentTime
+TextFile::length () const
+{
+       if (_subtitles.empty ()) {
+               return ContentTime ();
+       }
+
+       return ContentTime::from_seconds (_subtitles.back().to.all_as_seconds ());
+}
diff --git a/src/lib/text_file.h b/src/lib/text_file.h
new file mode 100644 (file)
index 0000000..346571f
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Copyright (C) 2014-2016 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/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_H
+#define DCPOMATIC_TEXT_SUBTITLE_H
+
+#include "dcpomatic_time.h"
+#include <sub/subtitle.h>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class TextFileContent;
+class text_file_time_test;
+class text_file_coordinate_test;
+class text_text_content_test;
+class text_file_parse_test;
+
+class TextFile
+{
+public:
+       explicit TextFile (boost::shared_ptr<const TextFileContent>);
+
+       ContentTime length () const;
+
+protected:
+       std::vector<sub::Subtitle> _subtitles;
+};
+
+#endif
diff --git a/src/lib/text_file_decoder.cc b/src/lib/text_file_decoder.cc
new file mode 100644 (file)
index 0000000..1dba3ac
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+    Copyright (C) 2014-2016 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 "text_file_decoder.h"
+#include "text_file_content.h"
+#include "text_content.h"
+#include <dcp/subtitle_string.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+using std::list;
+using std::vector;
+using std::string;
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+
+TextTextDecoder::TextTextDecoder (shared_ptr<const TextFileContent> content, shared_ptr<Log> log)
+       : TextFile (content)
+       , _next (0)
+{
+       subtitle.reset (new TextDecoder (this, content->subtitle, log));
+}
+
+void
+TextTextDecoder::seek (ContentTime time, bool accurate)
+{
+       /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
+          too many subtitles when seeking.
+       */
+       time -= ContentTime::from_seconds (5);
+       if (time < ContentTime()) {
+               time = ContentTime();
+       }
+
+       Decoder::seek (time, accurate);
+
+       _next = 0;
+       while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
+               ++_next;
+       }
+}
+
+bool
+TextTextDecoder::pass ()
+{
+       if (_next >= _subtitles.size ()) {
+               return true;
+       }
+
+       ContentTimePeriod const p = content_time_period (_subtitles[_next]);
+       subtitle->emit_text (p, _subtitles[_next]);
+
+       ++_next;
+       return false;
+}
+
+ContentTimePeriod
+TextTextDecoder::content_time_period (sub::Subtitle s) const
+{
+       return ContentTimePeriod (
+               ContentTime::from_seconds (s.from.all_as_seconds()),
+               ContentTime::from_seconds (s.to.all_as_seconds())
+               );
+}
diff --git a/src/lib/text_file_decoder.h b/src/lib/text_file_decoder.h
new file mode 100644 (file)
index 0000000..cd279ba
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Copyright (C) 2014-2016 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/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+
+#include "text_decoder.h"
+#include "text_file.h"
+
+class TextFileContent;
+
+class TextTextDecoder : public Decoder, public TextFile
+{
+public:
+       TextTextDecoder (boost::shared_ptr<const TextFileContent>, boost::shared_ptr<Log> log);
+
+       void seek (ContentTime time, bool accurate);
+       bool pass ();
+
+private:
+       ContentTimePeriod content_time_period (sub::Subtitle s) const;
+
+       size_t _next;
+};
+
+#endif
index 972e74b66417ae974bd98e1f94dacdf7593606a9..35acb90228bc42d0f9cc4b7827b7d883d6420b31 100644 (file)
@@ -21,7 +21,7 @@
 #include "text_subtitle.h"
 #include "cross.h"
 #include "exceptions.h"
 #include "text_subtitle.h"
 #include "cross.h"
 #include "exceptions.h"
-#include "text_subtitle_content.h"
+#include "text_text_content.h"
 #include <sub/subrip_reader.h>
 #include <sub/ssa_reader.h>
 #include <sub/collect.h>
 #include <sub/subrip_reader.h>
 #include <sub/ssa_reader.h>
 #include <sub/collect.h>
@@ -39,7 +39,7 @@ using boost::scoped_array;
 using boost::optional;
 using dcp::Data;
 
 using boost::optional;
 using dcp::Data;
 
-TextSubtitle::TextSubtitle (shared_ptr<const TextSubtitleContent> content)
+TextSubtitle::TextSubtitle (shared_ptr<const TextTextContent> content)
 {
        Data in (content->path (0));
 
 {
        Data in (content->path (0));
 
index c72486ca01ee6330b5dbfd5484338ffd2cf08d86..0cd33c9fb078eb9af4257746be3c3589a3dbc2df 100644 (file)
 #include <boost/shared_ptr.hpp>
 #include <vector>
 
 #include <boost/shared_ptr.hpp>
 #include <vector>
 
-class TextSubtitleContent;
+class TextTextContent;
 class text_subtitle_time_test;
 class text_subtitle_coordinate_test;
 class text_subtitle_time_test;
 class text_subtitle_coordinate_test;
-class text_subtitle_content_test;
+class text_text_content_test;
 class text_subtitle_parse_test;
 
 class TextSubtitle
 {
 public:
 class text_subtitle_parse_test;
 
 class TextSubtitle
 {
 public:
-       explicit TextSubtitle (boost::shared_ptr<const TextSubtitleContent>);
+       explicit TextSubtitle (boost::shared_ptr<const TextTextContent>);
 
        boost::optional<ContentTime> first () const;
        ContentTime length () const;
 
        boost::optional<ContentTime> first () const;
        ContentTime length () const;
diff --git a/src/lib/text_subtitle_content.cc b/src/lib/text_subtitle_content.cc
deleted file mode 100644 (file)
index 08722a0..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
-    Copyright (C) 2014-2016 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 "text_subtitle_content.h"
-#include "util.h"
-#include "text_subtitle.h"
-#include "film.h"
-#include "font.h"
-#include "subtitle_content.h"
-#include <dcp/raw_convert.h>
-#include <libxml++/libxml++.h>
-#include <iostream>
-
-#include "i18n.h"
-
-using std::string;
-using std::cout;
-using boost::shared_ptr;
-using dcp::raw_convert;
-
-TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, boost::filesystem::path path)
-       : Content (film, path)
-{
-       subtitle.reset (new SubtitleContent (this));
-}
-
-TextSubtitleContent::TextSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
-       : Content (film, node)
-       , _length (node->number_child<ContentTime::Type> ("Length"))
-{
-       subtitle = SubtitleContent::from_xml (this, node, version);
-}
-
-void
-TextSubtitleContent::examine (boost::shared_ptr<Job> job)
-{
-       Content::examine (job);
-       TextSubtitle s (shared_from_this ());
-
-       /* Default to turning these subtitles on */
-       subtitle->set_use (true);
-
-       boost::mutex::scoped_lock lm (_mutex);
-       _length = s.length ();
-       subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
-}
-
-string
-TextSubtitleContent::summary () const
-{
-       return path_summary() + " " + _("[subtitles]");
-}
-
-string
-TextSubtitleContent::technical_summary () const
-{
-       return Content::technical_summary() + " - " + _("Text subtitles");
-}
-
-void
-TextSubtitleContent::as_xml (xmlpp::Node* node, bool with_paths) const
-{
-       node->add_child("Type")->add_child_text ("TextSubtitle");
-       Content::as_xml (node, with_paths);
-
-       if (subtitle) {
-               subtitle->as_xml (node);
-       }
-
-       node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
-}
-
-DCPTime
-TextSubtitleContent::full_length () const
-{
-       FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
-       return DCPTime (_length, frc);
-}
diff --git a/src/lib/text_subtitle_content.h b/src/lib/text_subtitle_content.h
deleted file mode 100644 (file)
index fd0bad1..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
-    Copyright (C) 2014-2016 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 "content.h"
-
-class Job;
-
-/** @class TextSubtitleContent
- *  @brief SubRip or SSA subtitles.
- */
-class TextSubtitleContent : public Content
-{
-public:
-       TextSubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path);
-       TextSubtitleContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
-
-       boost::shared_ptr<TextSubtitleContent> shared_from_this () {
-               return boost::dynamic_pointer_cast<TextSubtitleContent> (Content::shared_from_this ());
-       }
-
-       void examine (boost::shared_ptr<Job>);
-       std::string summary () const;
-       std::string technical_summary () const;
-       void as_xml (xmlpp::Node *, bool with_paths) const;
-       DCPTime full_length () const;
-
-private:
-       ContentTime _length;
-};
diff --git a/src/lib/text_subtitle_decoder.cc b/src/lib/text_subtitle_decoder.cc
deleted file mode 100644 (file)
index 6188d52..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-    Copyright (C) 2014-2016 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 "text_subtitle_decoder.h"
-#include "text_subtitle_content.h"
-#include "subtitle_content.h"
-#include <dcp/subtitle_string.h>
-#include <boost/foreach.hpp>
-#include <iostream>
-
-using std::list;
-using std::vector;
-using std::string;
-using std::cout;
-using std::max;
-using boost::shared_ptr;
-using boost::optional;
-using boost::dynamic_pointer_cast;
-
-TextSubtitleDecoder::TextSubtitleDecoder (shared_ptr<const TextSubtitleContent> content, shared_ptr<Log> log)
-       : TextSubtitle (content)
-       , _next (0)
-{
-       ContentTime first;
-       if (!_subtitles.empty()) {
-               first = content_time_period(_subtitles[0]).from;
-       }
-       subtitle.reset (new SubtitleDecoder (this, content->subtitle, log, first));
-}
-
-void
-TextSubtitleDecoder::seek (ContentTime time, bool accurate)
-{
-       /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
-          too many subtitles when seeking.
-       */
-       time -= ContentTime::from_seconds (5);
-       if (time < ContentTime()) {
-               time = ContentTime();
-       }
-
-       Decoder::seek (time, accurate);
-
-       _next = 0;
-       while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
-               ++_next;
-       }
-}
-
-bool
-TextSubtitleDecoder::pass ()
-{
-       if (_next >= _subtitles.size ()) {
-               return true;
-       }
-
-       ContentTimePeriod const p = content_time_period (_subtitles[_next]);
-       subtitle->emit_text (p, _subtitles[_next]);
-
-       ++_next;
-       return false;
-}
-
-ContentTimePeriod
-TextSubtitleDecoder::content_time_period (sub::Subtitle s) const
-{
-       return ContentTimePeriod (
-               ContentTime::from_seconds (s.from.all_as_seconds()),
-               ContentTime::from_seconds (s.to.all_as_seconds())
-               );
-}
diff --git a/src/lib/text_subtitle_decoder.h b/src/lib/text_subtitle_decoder.h
deleted file mode 100644 (file)
index 72bb89b..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-    Copyright (C) 2014-2016 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/>.
-
-*/
-
-#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
-#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
-
-#include "subtitle_decoder.h"
-#include "text_subtitle.h"
-
-class TextSubtitleContent;
-
-class TextSubtitleDecoder : public Decoder, public TextSubtitle
-{
-public:
-       TextSubtitleDecoder (boost::shared_ptr<const TextSubtitleContent>, boost::shared_ptr<Log> log);
-
-       void seek (ContentTime time, bool accurate);
-       bool pass ();
-
-private:
-       ContentTimePeriod content_time_period (sub::Subtitle s) const;
-
-       size_t _next;
-};
-
-#endif
diff --git a/src/lib/text_text_content.cc b/src/lib/text_text_content.cc
new file mode 100644 (file)
index 0000000..1ff66c4
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+    Copyright (C) 2014-2016 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 "text_text_content.h"
+#include "util.h"
+#include "text_subtitle.h"
+#include "film.h"
+#include "font.h"
+#include "text_content.h"
+#include <dcp/raw_convert.h>
+#include <libxml++/libxml++.h>
+#include <iostream>
+
+#include "i18n.h"
+
+using std::string;
+using std::cout;
+using boost::shared_ptr;
+using dcp::raw_convert;
+
+TextTextContent::TextTextContent (shared_ptr<const Film> film, boost::filesystem::path path)
+       : Content (film, path)
+{
+       subtitle.reset (new TextContent (this));
+}
+
+TextTextContent::TextTextContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+       : Content (film, node)
+       , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+       subtitle = TextContent::from_xml (this, node, version);
+}
+
+void
+TextTextContent::examine (boost::shared_ptr<Job> job)
+{
+       Content::examine (job);
+       TextSubtitle s (shared_from_this ());
+
+       /* Default to turning these subtitles on */
+       subtitle->set_use (true);
+
+       boost::mutex::scoped_lock lm (_mutex);
+       _length = s.length ();
+       subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
+}
+
+string
+TextTextContent::summary () const
+{
+       return path_summary() + " " + _("[subtitles]");
+}
+
+string
+TextTextContent::technical_summary () const
+{
+       return Content::technical_summary() + " - " + _("Text subtitles");
+}
+
+void
+TextTextContent::as_xml (xmlpp::Node* node, bool with_paths) const
+{
+       node->add_child("Type")->add_child_text ("TextSubtitle");
+       Content::as_xml (node, with_paths);
+
+       if (subtitle) {
+               subtitle->as_xml (node);
+       }
+
+       node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
+}
+
+DCPTime
+TextTextContent::full_length () const
+{
+       FrameRateChange const frc (active_video_frame_rate(), film()->video_frame_rate ());
+       return DCPTime (_length, frc);
+}
diff --git a/src/lib/text_text_content.h b/src/lib/text_text_content.h
new file mode 100644 (file)
index 0000000..ccc86fb
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+    Copyright (C) 2014-2016 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 "content.h"
+
+class Job;
+
+/** @class TextTextContent
+ *  @brief SubRip or SSA subtitles.
+ */
+class TextTextContent : public Content
+{
+public:
+       TextTextContent (boost::shared_ptr<const Film>, boost::filesystem::path);
+       TextTextContent (boost::shared_ptr<const Film>, cxml::ConstNodePtr, int);
+
+       boost::shared_ptr<TextTextContent> shared_from_this () {
+               return boost::dynamic_pointer_cast<TextTextContent> (Content::shared_from_this ());
+       }
+
+       void examine (boost::shared_ptr<Job>);
+       std::string summary () const;
+       std::string technical_summary () const;
+       void as_xml (xmlpp::Node *, bool with_paths) const;
+       DCPTime full_length () const;
+
+private:
+       ContentTime _length;
+};
diff --git a/src/lib/text_text_decoder.cc b/src/lib/text_text_decoder.cc
new file mode 100644 (file)
index 0000000..2ae5cd3
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+    Copyright (C) 2014-2016 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 "text_text_decoder.h"
+#include "text_text_content.h"
+#include "text_content.h"
+#include <dcp/subtitle_string.h>
+#include <boost/foreach.hpp>
+#include <iostream>
+
+using std::list;
+using std::vector;
+using std::string;
+using std::cout;
+using std::max;
+using boost::shared_ptr;
+using boost::optional;
+using boost::dynamic_pointer_cast;
+
+TextTextDecoder::TextTextDecoder (shared_ptr<const TextTextContent> content, shared_ptr<Log> log)
+       : TextSubtitle (content)
+       , _next (0)
+{
+       ContentTime first;
+       if (!_subtitles.empty()) {
+               first = content_time_period(_subtitles[0]).from;
+       }
+       subtitle.reset (new TextDecoder (this, content->subtitle, log, first));
+}
+
+void
+TextTextDecoder::seek (ContentTime time, bool accurate)
+{
+       /* It's worth back-tracking a little here as decoding is cheap and it's nice if we don't miss
+          too many subtitles when seeking.
+       */
+       time -= ContentTime::from_seconds (5);
+       if (time < ContentTime()) {
+               time = ContentTime();
+       }
+
+       Decoder::seek (time, accurate);
+
+       _next = 0;
+       while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) {
+               ++_next;
+       }
+}
+
+bool
+TextTextDecoder::pass ()
+{
+       if (_next >= _subtitles.size ()) {
+               return true;
+       }
+
+       ContentTimePeriod const p = content_time_period (_subtitles[_next]);
+       subtitle->emit_text (p, _subtitles[_next]);
+
+       ++_next;
+       return false;
+}
+
+ContentTimePeriod
+TextTextDecoder::content_time_period (sub::Subtitle s) const
+{
+       return ContentTimePeriod (
+               ContentTime::from_seconds (s.from.all_as_seconds()),
+               ContentTime::from_seconds (s.to.all_as_seconds())
+               );
+}
diff --git a/src/lib/text_text_decoder.h b/src/lib/text_text_decoder.h
new file mode 100644 (file)
index 0000000..daaf2fc
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+    Copyright (C) 2014-2016 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/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+#define DCPOMATIC_TEXT_SUBTITLE_DECODER_H
+
+#include "text_decoder.h"
+#include "text_subtitle.h"
+
+class TextTextContent;
+
+class TextTextDecoder : public Decoder, public TextSubtitle
+{
+public:
+       TextTextDecoder (boost::shared_ptr<const TextTextContent>, boost::shared_ptr<Log> log);
+
+       void seek (ContentTime time, bool accurate);
+       bool pass ();
+
+private:
+       ContentTimePeriod content_time_period (sub::Subtitle s) const;
+
+       size_t _next;
+};
+
+#endif
index dfce6aec54be448c4c3e87658576783ca5ebba77..af2171718837ae9ba439dfc529a77e0c4a49734d 100644 (file)
@@ -31,7 +31,7 @@
 class Content;
 class VideoContent;
 class AudioContent;
 class Content;
 class VideoContent;
 class AudioContent;
-class SubtitleContent;
+class TextContent;
 class FFmpegContent;
 
 namespace cxml {
 class FFmpegContent;
 
 namespace cxml {
index b6784dbaae47eaefaf3a46b5f5290bb00ffd89e9..4a7132e48d3a444ed96f2fea405fb3cf87d0e233 100644 (file)
@@ -55,8 +55,8 @@ sources = """
           dcp_encoder.cc
           dcp_examiner.cc
           dcp_subtitle.cc
           dcp_encoder.cc
           dcp_examiner.cc
           dcp_subtitle.cc
-          dcp_subtitle_content.cc
-          dcp_subtitle_decoder.cc
+          dcp_text_content.cc
+          dcp_text_decoder.cc
           dcp_video.cc
           dcpomatic_socket.cc
           dcpomatic_time.cc
           dcp_video.cc
           dcpomatic_socket.cc
           dcpomatic_time.cc
@@ -132,11 +132,11 @@ sources = """
           server.cc
           shuffler.cc
           string_log_entry.cc
           server.cc
           shuffler.cc
           string_log_entry.cc
-          subtitle_content.cc
-          subtitle_decoder.cc
+          text_content.cc
+          text_decoder.cc
           text_subtitle.cc
           text_subtitle.cc
-          text_subtitle_content.cc
-          text_subtitle_decoder.cc
+          text_text_content.cc
+          text_text_decoder.cc
           timer.cc
           transcode_job.cc
           types.cc
           timer.cc
           transcode_job.cc
           types.cc
index 64c11281c276529063c5f70dd293ce3a5ddf0853..934e5750521900c0c1487e7824ea55b9ea0be03b 100644 (file)
@@ -71,7 +71,7 @@
 #include "lib/transcode_job.h"
 #include "lib/dkdm_wrapper.h"
 #include "lib/audio_content.h"
 #include "lib/transcode_job.h"
 #include "lib/dkdm_wrapper.h"
 #include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include <dcp/exceptions.h>
 #include <dcp/raw_convert.h>
 #include <wx/generic/aboutdlgg.h>
 #include <dcp/exceptions.h>
 #include <dcp/raw_convert.h>
 #include <wx/generic/aboutdlgg.h>
index 29195777ec040ee0247e836122cb5ffcdbd682d9..3f56f47529fd59b41397f73b0d023ecda58e22cb 100644 (file)
@@ -27,7 +27,7 @@
 #include "lib/job_manager.h"
 #include "lib/job.h"
 #include "lib/video_content.h"
 #include "lib/job_manager.h"
 #include "lib/job.h"
 #include "lib/video_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/ratio.h"
 #include "lib/verify_dcp_job.h"
 #include "lib/dcp_examiner.h"
 #include "lib/ratio.h"
 #include "lib/verify_dcp_job.h"
 #include "lib/dcp_examiner.h"
index 4adeb90a4e610b096b22112be778f68da1c52fe3..2c0f35f6cae478dc6d1d3dc42a53b8a1c9f3665e 100644 (file)
@@ -28,7 +28,7 @@
 #include "image_sequence_dialog.h"
 #include "film_viewer.h"
 #include "lib/audio_content.h"
 #include "image_sequence_dialog.h"
 #include "film_viewer.h"
 #include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/video_content.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
 #include "lib/video_content.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
@@ -39,7 +39,7 @@
 #include "lib/config.h"
 #include "lib/log.h"
 #include "lib/compose.hpp"
 #include "lib/config.h"
 #include "lib/log.h"
 #include "lib/compose.hpp"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/text_subtitle.h"
 #include <wx/wx.h>
 #include <wx/notebook.h>
 #include "lib/text_subtitle.h"
 #include <wx/wx.h>
 #include <wx/notebook.h>
@@ -258,11 +258,11 @@ ContentPanel::selection_changed ()
        BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
                DCPTime p;
                p = i->position();
        BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
                DCPTime p;
                p = i->position();
-               if (dynamic_pointer_cast<TextSubtitleContent>(i) && i->paths_valid()) {
+               if (dynamic_pointer_cast<TextTextContent>(i) && i->paths_valid()) {
                        /* Rather special case; if we select a text subtitle file jump to its
                           first subtitle.
                        */
                        /* Rather special case; if we select a text subtitle file jump to its
                           first subtitle.
                        */
-                       TextSubtitle ts (dynamic_pointer_cast<TextSubtitleContent>(i));
+                       TextSubtitle ts (dynamic_pointer_cast<TextTextContent>(i));
                        if (ts.first()) {
                                p += DCPTime(ts.first().get(), _film->active_frame_rate_change(i->position()));
                        }
                        if (ts.first()) {
                                p += DCPTime(ts.first().get(), _film->active_frame_rate_change(i->position()));
                        }
index f2783af6b94d0bc49db4edd8655aa577c0bb6056..5a380ec4e71ce567a60a7076a7f330c1a6c744e1 100644 (file)
@@ -32,7 +32,7 @@
 #include "lib/ffmpeg_content.h"
 #include "lib/audio_processor.h"
 #include "lib/video_content.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/audio_processor.h"
 #include "lib/video_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/dcp_content.h"
 #include "lib/audio_content.h"
 #include <dcp/locale_convert.h>
 #include "lib/dcp_content.h"
 #include "lib/audio_content.h"
 #include <dcp/locale_convert.h>
@@ -433,8 +433,8 @@ void
 DCPPanel::film_content_changed (int property)
 {
        if (property == AudioContentProperty::STREAMS ||
 DCPPanel::film_content_changed (int property)
 {
        if (property == AudioContentProperty::STREAMS ||
-           property == SubtitleContentProperty::USE ||
-           property == SubtitleContentProperty::BURN ||
+           property == TextContentProperty::USE ||
+           property == TextContentProperty::BURN ||
            property == VideoContentProperty::SCALE ||
            property == DCPContentProperty::REFERENCE_VIDEO ||
            property == DCPContentProperty::REFERENCE_AUDIO ||
            property == VideoContentProperty::SCALE ||
            property == DCPContentProperty::REFERENCE_VIDEO ||
            property == DCPContentProperty::REFERENCE_AUDIO ||
index c85d18e342d37a096f270c51af316c79b8b12cb2..c295ec327f79b9b81060c02fcb9328d455f0d54d 100644 (file)
@@ -24,7 +24,7 @@
 #include "font_files_dialog.h"
 #include "lib/font.h"
 #include "lib/content.h"
 #include "font_files_dialog.h"
 #include "lib/font.h"
 #include "lib/content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include <wx/wx.h>
 #include <boost/foreach.hpp>
 #include <iostream>
 #include <wx/wx.h>
 #include <boost/foreach.hpp>
 #include <iostream>
index 8ae4797469f2d3bd27eaadf4111ffb938dd58ea7..f78ed9ab5ed4b585640e9e9cbd849661bb242f0e 100644 (file)
@@ -20,8 +20,8 @@
 
 #include "subtitle_appearance_dialog.h"
 #include "rgba_colour_picker.h"
 
 #include "subtitle_appearance_dialog.h"
 #include "rgba_colour_picker.h"
-#include "lib/text_subtitle_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_text_content.h"
+#include "lib/text_content.h"
 #include "lib/ffmpeg_subtitle_stream.h"
 #include "lib/ffmpeg_content.h"
 #include <wx/wx.h>
 #include "lib/ffmpeg_subtitle_stream.h"
 #include "lib/ffmpeg_content.h"
 #include <wx/wx.h>
index 1a42c1f57a9ad7256174aeb0f1918df6a9969f79..da7891ca8eb1f41d44acd6f4594340dbbc6f550a 100644 (file)
 #include "fonts_dialog.h"
 #include "subtitle_appearance_dialog.h"
 #include "lib/ffmpeg_content.h"
 #include "fonts_dialog.h"
 #include "subtitle_appearance_dialog.h"
 #include "lib/ffmpeg_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/ffmpeg_subtitle_stream.h"
 #include "lib/ffmpeg_subtitle_stream.h"
-#include "lib/dcp_subtitle_content.h"
-#include "lib/text_subtitle_decoder.h"
-#include "lib/dcp_subtitle_decoder.h"
+#include "lib/dcp_text_content.h"
+#include "lib/text_text_decoder.h"
+#include "lib/dcp_text_decoder.h"
 #include "lib/dcp_content.h"
 #include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/decoder_factory.h"
 #include <wx/spinctrl.h>
 #include <boost/foreach.hpp>
 #include "lib/decoder_factory.h"
 #include <wx/spinctrl.h>
 #include <boost/foreach.hpp>
@@ -209,22 +209,22 @@ SubtitlePanel::film_content_changed (int property)
                        }
                }
                setup_sensitivity ();
                        }
                }
                setup_sensitivity ();
-       } else if (property == SubtitleContentProperty::USE) {
+       } else if (property == TextContentProperty::USE) {
                checked_set (_use, scs ? scs->subtitle->use() : false);
                setup_sensitivity ();
                checked_set (_use, scs ? scs->subtitle->use() : false);
                setup_sensitivity ();
-       } else if (property == SubtitleContentProperty::BURN) {
+       } else if (property == TextContentProperty::BURN) {
                checked_set (_burn, scs ? scs->subtitle->burn() : false);
                checked_set (_burn, scs ? scs->subtitle->burn() : false);
-       } else if (property == SubtitleContentProperty::X_OFFSET) {
+       } else if (property == TextContentProperty::X_OFFSET) {
                checked_set (_x_offset, scs ? lrint (scs->subtitle->x_offset() * 100) : 0);
                checked_set (_x_offset, scs ? lrint (scs->subtitle->x_offset() * 100) : 0);
-       } else if (property == SubtitleContentProperty::Y_OFFSET) {
+       } else if (property == TextContentProperty::Y_OFFSET) {
                checked_set (_y_offset, scs ? lrint (scs->subtitle->y_offset() * 100) : 0);
                checked_set (_y_offset, scs ? lrint (scs->subtitle->y_offset() * 100) : 0);
-       } else if (property == SubtitleContentProperty::X_SCALE) {
+       } else if (property == TextContentProperty::X_SCALE) {
                checked_set (_x_scale, scs ? lrint (scs->subtitle->x_scale() * 100) : 100);
                checked_set (_x_scale, scs ? lrint (scs->subtitle->x_scale() * 100) : 100);
-       } else if (property == SubtitleContentProperty::Y_SCALE) {
+       } else if (property == TextContentProperty::Y_SCALE) {
                checked_set (_y_scale, scs ? lrint (scs->subtitle->y_scale() * 100) : 100);
                checked_set (_y_scale, scs ? lrint (scs->subtitle->y_scale() * 100) : 100);
-       } else if (property == SubtitleContentProperty::LINE_SPACING) {
+       } else if (property == TextContentProperty::LINE_SPACING) {
                checked_set (_line_spacing, scs ? lrint (scs->subtitle->line_spacing() * 100) : 100);
                checked_set (_line_spacing, scs ? lrint (scs->subtitle->line_spacing() * 100) : 100);
-       } else if (property == SubtitleContentProperty::LANGUAGE) {
+       } else if (property == TextContentProperty::LANGUAGE) {
                checked_set (_language, scs ? scs->subtitle->language() : "");
        } else if (property == DCPContentProperty::REFERENCE_SUBTITLE) {
                if (scs) {
                checked_set (_language, scs ? scs->subtitle->language() : "");
        } else if (property == DCPContentProperty::REFERENCE_SUBTITLE) {
                if (scs) {
@@ -265,9 +265,9 @@ SubtitlePanel::setup_sensitivity ()
        BOOST_FOREACH (shared_ptr<Content> i, sel) {
                /* These are the content types that could include subtitles */
                shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (i);
        BOOST_FOREACH (shared_ptr<Content> i, sel) {
                /* These are the content types that could include subtitles */
                shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (i);
-               shared_ptr<const TextSubtitleContent> sc = boost::dynamic_pointer_cast<const TextSubtitleContent> (i);
+               shared_ptr<const TextTextContent> sc = boost::dynamic_pointer_cast<const TextTextContent> (i);
                shared_ptr<const DCPContent> dc = boost::dynamic_pointer_cast<const DCPContent> (i);
                shared_ptr<const DCPContent> dc = boost::dynamic_pointer_cast<const DCPContent> (i);
-               shared_ptr<const DCPSubtitleContent> dsc = boost::dynamic_pointer_cast<const DCPSubtitleContent> (i);
+               shared_ptr<const DCPTextContent> dsc = boost::dynamic_pointer_cast<const DCPTextContent> (i);
                if (fc) {
                        if (fc->subtitle) {
                                ++ffmpeg_subs;
                if (fc) {
                        if (fc->subtitle) {
                                ++ffmpeg_subs;
@@ -383,15 +383,15 @@ void
 SubtitlePanel::content_selection_changed ()
 {
        film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
 SubtitlePanel::content_selection_changed ()
 {
        film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
-       film_content_changed (SubtitleContentProperty::USE);
-       film_content_changed (SubtitleContentProperty::BURN);
-       film_content_changed (SubtitleContentProperty::X_OFFSET);
-       film_content_changed (SubtitleContentProperty::Y_OFFSET);
-       film_content_changed (SubtitleContentProperty::X_SCALE);
-       film_content_changed (SubtitleContentProperty::Y_SCALE);
-       film_content_changed (SubtitleContentProperty::LINE_SPACING);
-       film_content_changed (SubtitleContentProperty::LANGUAGE);
-       film_content_changed (SubtitleContentProperty::FONTS);
+       film_content_changed (TextContentProperty::USE);
+       film_content_changed (TextContentProperty::BURN);
+       film_content_changed (TextContentProperty::X_OFFSET);
+       film_content_changed (TextContentProperty::Y_OFFSET);
+       film_content_changed (TextContentProperty::X_SCALE);
+       film_content_changed (TextContentProperty::Y_SCALE);
+       film_content_changed (TextContentProperty::LINE_SPACING);
+       film_content_changed (TextContentProperty::LANGUAGE);
+       film_content_changed (TextContentProperty::FONTS);
        film_content_changed (DCPContentProperty::REFERENCE_SUBTITLE);
 }
 
        film_content_changed (DCPContentProperty::REFERENCE_SUBTITLE);
 }
 
index cedf273d4fb7cc36444aa187f888a0ad04964235..7efe10d0ce2c48cd2c8b0b396a50b419b493bd64 100644 (file)
 
 */
 
 
 */
 
-#include "lib/text_subtitle_decoder.h"
+#include "lib/text_text_decoder.h"
 #include "lib/content_subtitle.h"
 #include "lib/video_decoder.h"
 #include "lib/audio_decoder.h"
 #include "lib/film.h"
 #include "lib/content_subtitle.h"
 #include "lib/video_decoder.h"
 #include "lib/audio_decoder.h"
 #include "lib/film.h"
-#include "lib/text_subtitle_content.h"
 #include "lib/config.h"
 #include "lib/config.h"
+#include "lib/text_text_content.h"
 #include "subtitle_view.h"
 #include "film_viewer.h"
 #include "wx_util.h"
 #include "subtitle_view.h"
 #include "film_viewer.h"
 #include "wx_util.h"
index e96b474cf55dd7413283f53303e126fc715ba0a8..d0a898b18f645d3d469c997b039f88ed138f78ed 100644 (file)
@@ -25,7 +25,7 @@
 #include "timeline_labels_view.h"
 #include "timeline_video_content_view.h"
 #include "timeline_audio_content_view.h"
 #include "timeline_labels_view.h"
 #include "timeline_video_content_view.h"
 #include "timeline_audio_content_view.h"
-#include "timeline_subtitle_content_view.h"
+#include "timeline_text_content_view.h"
 #include "timeline_atmos_content_view.h"
 #include "content_panel.h"
 #include "wx_util.h"
 #include "timeline_atmos_content_view.h"
 #include "content_panel.h"
 #include "wx_util.h"
@@ -34,7 +34,7 @@
 #include "lib/image_content.h"
 #include "lib/timer.h"
 #include "lib/audio_content.h"
 #include "lib/image_content.h"
 #include "lib/timer.h"
 #include "lib/audio_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/video_content.h"
 #include "lib/atmos_mxf_content.h"
 #include <wx/graphics.h>
 #include "lib/video_content.h"
 #include "lib/atmos_mxf_content.h"
 #include <wx/graphics.h>
@@ -229,7 +229,7 @@ Timeline::recreate_views ()
                }
 
                if (i->subtitle) {
                }
 
                if (i->subtitle) {
-                       _views.push_back (shared_ptr<TimelineView> (new TimelineSubtitleContentView (*this, i)));
+                       _views.push_back (shared_ptr<TimelineView> (new TimelineTextContentView (*this, i)));
                }
 
                if (dynamic_pointer_cast<AtmosMXFContent> (i)) {
                }
 
                if (dynamic_pointer_cast<AtmosMXFContent> (i)) {
@@ -375,7 +375,7 @@ Timeline::assign_tracks ()
 
        /* Subtitle */
 
 
        /* Subtitle */
 
-       int const subtitle_tracks = place<TimelineSubtitleContentView> (_views, _tracks);
+       int const subtitle_tracks = place<TimelineTextContentView> (_views, _tracks);
 
        /* Atmos */
 
 
        /* Atmos */
 
diff --git a/src/wx/timeline_subtitle_content_view.cc b/src/wx/timeline_subtitle_content_view.cc
deleted file mode 100644 (file)
index f5c7852..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
-    Copyright (C) 2013-2016 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 "timeline_subtitle_content_view.h"
-#include "lib/subtitle_content.h"
-#include "lib/content.h"
-
-using boost::shared_ptr;
-
-TimelineSubtitleContentView::TimelineSubtitleContentView (Timeline& tl, shared_ptr<Content> c)
-       : TimelineContentView (tl, c)
-{
-
-}
-
-wxColour
-TimelineSubtitleContentView::background_colour () const
-{
-       if (!active ()) {
-               return wxColour (210, 210, 210, 128);
-       }
-
-       return wxColour (163, 255, 154, 255);
-}
-
-wxColour
-TimelineSubtitleContentView::foreground_colour () const
-{
-       if (!active ()) {
-               return wxColour (180, 180, 180, 128);
-       }
-
-       return wxColour (0, 0, 0, 255);
-}
-
-bool
-TimelineSubtitleContentView::active () const
-{
-       shared_ptr<Content> c = _content.lock ();
-       DCPOMATIC_ASSERT (c);
-       return c->subtitle && c->subtitle->use();
-}
diff --git a/src/wx/timeline_subtitle_content_view.h b/src/wx/timeline_subtitle_content_view.h
deleted file mode 100644 (file)
index a7a15f9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-    Copyright (C) 2013-2016 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 "timeline_content_view.h"
-
-class SubtitleContent;
-
-/** @class TimelineSubtitleContentView
- *  @brief Timeline view for SubtitleContent.
- */
-class TimelineSubtitleContentView : public TimelineContentView
-{
-public:
-       TimelineSubtitleContentView (Timeline& tl, boost::shared_ptr<Content> c);
-
-private:
-       bool active () const;
-       wxColour background_colour () const;
-       wxColour foreground_colour () const;
-};
diff --git a/src/wx/timeline_text_content_view.cc b/src/wx/timeline_text_content_view.cc
new file mode 100644 (file)
index 0000000..b4820bf
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+    Copyright (C) 2013-2016 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 "timeline_text_content_view.h"
+#include "lib/text_content.h"
+#include "lib/content.h"
+
+using boost::shared_ptr;
+
+TimelineTextContentView::TimelineTextContentView (Timeline& tl, shared_ptr<Content> c)
+       : TimelineContentView (tl, c)
+{
+
+}
+
+wxColour
+TimelineTextContentView::background_colour () const
+{
+       if (!active ()) {
+               return wxColour (210, 210, 210, 128);
+       }
+
+       return wxColour (163, 255, 154, 255);
+}
+
+wxColour
+TimelineTextContentView::foreground_colour () const
+{
+       if (!active ()) {
+               return wxColour (180, 180, 180, 128);
+       }
+
+       return wxColour (0, 0, 0, 255);
+}
+
+bool
+TimelineTextContentView::active () const
+{
+       shared_ptr<Content> c = _content.lock ();
+       DCPOMATIC_ASSERT (c);
+       return c->subtitle && c->subtitle->use();
+}
diff --git a/src/wx/timeline_text_content_view.h b/src/wx/timeline_text_content_view.h
new file mode 100644 (file)
index 0000000..540a906
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    Copyright (C) 2013-2016 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 "timeline_content_view.h"
+
+class TextContent;
+
+/** @class TimelineTextContentView
+ *  @brief Timeline view for TextContent.
+ */
+class TimelineTextContentView : public TimelineContentView
+{
+public:
+       TimelineTextContentView (Timeline& tl, boost::shared_ptr<Content> c);
+
+private:
+       bool active () const;
+       wxColour background_colour () const;
+       wxColour foreground_colour () const;
+};
index 4006c5d3e7625de67e7124172c1893508572c95f..315ead52430eb641339f964a8e2385fb01f6ae81 100644 (file)
 #include "move_to_dialog.h"
 #include "lib/content.h"
 #include "lib/image_content.h"
 #include "move_to_dialog.h"
 #include "lib/content.h"
 #include "lib/image_content.h"
-#include "lib/subtitle_content.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/text_content.h"
+#include "lib/dcp_text_content.h"
 #include "lib/audio_content.h"
 #include "lib/audio_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/video_content.h"
 #include <dcp/locale_convert.h>
 #include <boost/foreach.hpp>
 #include "lib/video_content.h"
 #include <dcp/locale_convert.h>
 #include <boost/foreach.hpp>
index b5210bacee2a91d226d24c4174ddb63ac4cd9307..d5adafebe44e45f0dff55310ac19d516237913db 100644 (file)
@@ -109,7 +109,7 @@ sources = """
           timeline_dialog.cc
           timeline_audio_content_view.cc
           timeline_labels_view.cc
           timeline_dialog.cc
           timeline_audio_content_view.cc
           timeline_labels_view.cc
-          timeline_subtitle_content_view.cc
+          timeline_text_content_view.cc
           timeline_reels_view.cc
           timeline_time_axis_view.cc
           timeline_video_content_view.cc
           timeline_reels_view.cc
           timeline_time_axis_view.cc
           timeline_video_content_view.cc
index 184be5a82dd27dd6cd2548fc00c7dc6c6d0f8321..f0e60284b18d3a8a224af5b072e7e4c1cfe0a66e 100644 (file)
  *  @ingroup specific
  */
 
  *  @ingroup specific
  */
 
-#include "lib/text_subtitle_content.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/text_text_content.h"
+#include "lib/dcp_text_content.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/dcp_content.h"
 #include "lib/content_factory.h"
 #include "lib/config.h"
 #include "lib/dcp_content.h"
 #include "lib/content_factory.h"
 #include "lib/config.h"
@@ -59,7 +59,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_subrip)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
        content->subtitle->set_use (true);
        content->subtitle->set_burn (true);
        film->examine_and_add_content (content);
        content->subtitle->set_use (true);
        content->subtitle->set_burn (true);
        film->examine_and_add_content (content);
@@ -77,7 +77,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_dcp)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
+       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub.xml"));
        content->subtitle->set_use (true);
        film->examine_and_add_content (content);
        wait_for_jobs ();
        content->subtitle->set_use (true);
        film->examine_and_add_content (content);
        wait_for_jobs ();
@@ -106,7 +106,7 @@ BOOST_AUTO_TEST_CASE (burnt_subtitle_test_onto_dcp)
        film2->set_name ("frobozz");
        shared_ptr<DCPContent> background_dcp (new DCPContent(film2, film->dir(film->dcp_name())));
        film2->examine_and_add_content (background_dcp);
        film2->set_name ("frobozz");
        shared_ptr<DCPContent> background_dcp (new DCPContent(film2, film->dir(film->dcp_name())));
        film2->examine_and_add_content (background_dcp);
-       shared_ptr<TextSubtitleContent> sub = dynamic_pointer_cast<TextSubtitleContent> (
+       shared_ptr<TextTextContent> sub = dynamic_pointer_cast<TextTextContent> (
                content_factory(film2, "test/data/subrip2.srt").front()
                );
        sub->subtitle->set_burn (true);
                content_factory(film2, "test/data/subrip2.srt").front()
                );
        sub->subtitle->set_burn (true);
index 283fe8fcd20a543aa122d3f6f41e9b186d544d3b..c57d694d0718c2c477f5f3126b564a441dd70344 100644 (file)
 
 #include <boost/test/unit_test.hpp>
 #include "lib/film.h"
 
 #include <boost/test/unit_test.hpp>
 #include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
 #include "lib/dcp_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_decoder.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_decoder.h"
 #include "lib/dcp_content_type.h"
-#include "lib/dcp_subtitle_decoder.h"
-#include "lib/subtitle_content.h"
+#include "lib/dcp_text_decoder.h"
+#include "lib/text_content.h"
 #include "lib/content_subtitle.h"
 #include "lib/content_subtitle.h"
-#include "lib/subtitle_decoder.h"
 #include "lib/font.h"
 #include "lib/font.h"
+#include "lib/text_decoder.h"
 #include "test.h"
 #include <iostream>
 
 #include "test.h"
 #include <iostream>
 
@@ -65,7 +65,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (false);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (false);
-       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
+       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
@@ -109,11 +109,11 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test2)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub2.xml"));
+       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub2.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
+       shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
        decoder->subtitle->TextStart.connect (bind (store, _1));
 
        stored = optional<ContentTextSubtitle> ();
        decoder->subtitle->TextStart.connect (bind (store, _1));
 
        stored = optional<ContentTextSubtitle> ();
@@ -132,14 +132,14 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test3)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (true);
-       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub3.xml"));
+       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub3.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
+       shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
        stored = optional<ContentTextSubtitle> ();
        while (!decoder->pass ()) {
                decoder->subtitle->TextStart.connect (bind (store, _1));
        stored = optional<ContentTextSubtitle> ();
        while (!decoder->pass ()) {
                decoder->subtitle->TextStart.connect (bind (store, _1));
index fc53ee40c3221049eddd97d1c30589ea9ce8f15c..cfe607b8df5fd74b8e86bc0d64f92e643a01ee38 100644 (file)
 #include "lib/image_content.h"
 #include "lib/video_content.h"
 #include "lib/audio_content.h"
 #include "lib/image_content.h"
 #include "lib/video_content.h"
 #include "lib/audio_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/ratio.h"
 #include "lib/transcode_job.h"
 #include "lib/dcp_content.h"
 #include "lib/ratio.h"
 #include "lib/transcode_job.h"
 #include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/compose.hpp"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include "lib/compose.hpp"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test6)
        film->set_container (Ratio::from_id ("185"));
        film->set_audio_channels (6);
 
        film->set_container (Ratio::from_id ("185"));
        film->set_audio_channels (6);
 
-       shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip2.srt"));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test7)
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+       shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
@@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test2)
        film->set_container (Ratio::from_id ("185"));
        film->set_audio_channels (6);
 
        film->set_container (Ratio::from_id ("185"));
        film->set_audio_channels (6);
 
-       shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip2.srt"));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
@@ -197,7 +197,7 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test3)
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+       shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
        s->subtitle->set_colour (dcp::Colour (255, 255, 0));
index 1f5247392a461b6dd90033b4189a7a18c2f02b7c..c12f15fa1e726c1c4bc411a69549931a074cdb7d 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "test.h"
 #include "lib/film.h"
 
 #include "test.h"
 #include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
index 52f3097cbf891f8963db5ad838884f11ef17e108..f59205e16693357b0371b3ff692b1aff96f49348 100644 (file)
 #include "lib/player.h"
 #include "lib/video_content.h"
 #include "lib/image_content.h"
 #include "lib/player.h"
 #include "lib/video_content.h"
 #include "lib/image_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/content_factory.h"
 #include "lib/dcp_content.h"
 #include "lib/content_factory.h"
 #include "lib/dcp_content.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/butler.h"
 #include "lib/compose.hpp"
 #include "test.h"
 #include "lib/butler.h"
 #include "lib/compose.hpp"
 #include "test.h"
@@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE (player_interleave_test)
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (c);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<TextSubtitleContent> s (new TextSubtitleContent (film, "test/data/subrip.srt"));
+       shared_ptr<TextTextContent> s (new TextTextContent (film, "test/data/subrip.srt"));
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (s);
        BOOST_REQUIRE (!wait_for_jobs ());
 
index d705d8769c528877814a684dfe43dca7677ca91f..f793cef1d32f4ec5355cf1b7352dbb0394c26b17 100644 (file)
@@ -30,7 +30,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
 #include "lib/video_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
 #include "lib/video_content.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/content_factory.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include "lib/content_factory.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE (reels_test3)
 
        shared_ptr<Content> dcp (new DCPContent (film, "test/data/reels_test2"));
        film->examine_and_add_content (dcp);
 
        shared_ptr<Content> dcp (new DCPContent (film, "test/data/reels_test2"));
        film->examine_and_add_content (dcp);
-       shared_ptr<Content> sub (new TextSubtitleContent (film, "test/data/subrip.srt"));
+       shared_ptr<Content> sub (new TextTextContent (film, "test/data/subrip.srt"));
        film->examine_and_add_content (sub);
        wait_for_jobs ();
 
        film->examine_and_add_content (sub);
        wait_for_jobs ();
 
@@ -206,7 +206,7 @@ BOOST_AUTO_TEST_CASE (reels_test4)
                content[i]->video->set_length (24);
        }
 
                content[i]->video->set_length (24);
        }
 
-       shared_ptr<TextSubtitleContent> subs (new TextSubtitleContent (film, "test/data/subrip3.srt"));
+       shared_ptr<TextTextContent> subs (new TextTextContent (film, "test/data/subrip3.srt"));
        film->examine_and_add_content (subs);
        wait_for_jobs ();
 
        film->examine_and_add_content (subs);
        wait_for_jobs ();
 
index 43ed16ebb1f478088f39e7220b094b4b56d7adb5..e7e9c67b2dc3758ef015ce870115637c4bcec7aa 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/job_manager.h"
 #include "lib/film.h"
 #include "lib/dcp_content.h"
 #include "lib/job_manager.h"
 #include "lib/film.h"
 #include "lib/dcp_content.h"
index bc6d4179866af71799a77de035912232e9a34bab..4e286523f9259c467f5eebcb6fde3fd7b06ff0b4 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/film.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include "lib/film.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
index 7c89749e20dac27c646700929f713ee009967958..d931cf8033e4400f22caa42e44e97e1087bfcd40 100644 (file)
  */
 
 #include "lib/film.h"
  */
 
 #include "lib/film.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test)
        film->set_name ("frobozz");
        film->set_audio_channels (6);
        film->set_interop (false);
        film->set_name ("frobozz");
        film->set_audio_channels (6);
        film->set_interop (false);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
@@ -69,7 +69,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test2)
        film->set_name ("frobozz");
        film->set_audio_channels (6);
        film->set_interop (false);
        film->set_name ("frobozz");
        film->set_audio_channels (6);
        film->set_interop (false);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
@@ -104,7 +104,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test3)
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_audio_channels (6);
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_audio_channels (6);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, private_data / "Ankoemmling_short.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, private_data / "Ankoemmling_short.srt"));
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
@@ -125,7 +125,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (false);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (false);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
@@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test5)
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_sequence (false);
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_sequence (false);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip2.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip2.srt"));
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
@@ -164,7 +164,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test6)
 {
        shared_ptr<Film> film = new_test_film2 ("srt_subtitle_test6");
        film->set_interop (false);
 {
        shared_ptr<Film> film = new_test_film2 ("srt_subtitle_test6");
        film->set_interop (false);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/frames.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/frames.srt"));
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
        content->subtitle->set_use (true);
        content->subtitle->set_burn (false);
        film->examine_and_add_content (content);
@@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test6)
 BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
 {
        shared_ptr<Film> film = new_test_film ("subrip_render_test");
 BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
 {
        shared_ptr<Film> film = new_test_film ("subrip_render_test");
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip.srt"));
        content->examine (shared_ptr<Job> (), true);
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
 
        content->examine (shared_ptr<Job> (), true);
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
 
index bf460247c7ccf174ef9023fd73e56efe518db6b4..b8d7a7c911e44ec9eb676916b831ff6c65b11888 100644 (file)
  */
 
 #include "lib/film.h"
  */
 
 #include "lib/film.h"
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
@@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE (ssa_subtitle_test1)
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (true);
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_interop (true);
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, private_data / "DKH_UT_EN20160601def.ssa"));
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
index 3eede3a8845e66fcea7c74d728b1f755fe8f5d18..749ef9e73773d798b2da70b79f76a47b6ea9fdb8 100644 (file)
 
 */
 
 
 */
 
-#include "lib/text_subtitle_content.h"
+#include "lib/text_text_content.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
-#include "lib/subtitle_content.h"
+#include "lib/text_content.h"
 #include "lib/dcp_content_type.h"
 #include "test.h"
 #include <dcp/cpl.h>
 #include "lib/dcp_content_type.h"
 #include "test.h"
 #include <dcp/cpl.h>
@@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE (subtitle_reel_number_test)
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
        film->set_container (Ratio::from_id ("185"));
        film->set_dcp_content_type (DCPContentType::from_isdcf_name ("TLR"));
        film->set_name ("frobozz");
-       shared_ptr<TextSubtitleContent> content (new TextSubtitleContent (film, "test/data/subrip5.srt"));
+       shared_ptr<TextTextContent> content (new TextTextContent (film, "test/data/subrip5.srt"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
        content->subtitle->set_use (true);
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
        content->subtitle->set_use (true);
index 33bcf823f2deb69aec1963c58da1f54f778b9d76..1174eb583e513f7d1bb8e82a5a9bf24d38107d0e 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 #include "lib/film.h"
 */
 
 #include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 
@@ -29,7 +29,7 @@ using boost::shared_ptr;
 BOOST_AUTO_TEST_CASE (subtitle_trim_test1)
 {
        shared_ptr<Film> film = new_test_film2 ("subtitle_trim_test1");
 BOOST_AUTO_TEST_CASE (subtitle_trim_test1)
 {
        shared_ptr<Film> film = new_test_film2 ("subtitle_trim_test1");
-       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub5.xml"));
+       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub5.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
index 8b6e215bade6e42fdcdfd8161eb67c008898a6e2..1ed5ac81061d1167d2269eb83d56dd5fa5084e10 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "test.h"
 #include "lib/film.h"
 
 #include "test.h"
 #include "lib/film.h"
-#include "lib/dcp_subtitle_content.h"
+#include "lib/dcp_text_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"