Clean up after previous commit.
authorCarl Hetherington <cth@carlh.net>
Thu, 19 Jul 2018 21:44:53 +0000 (22:44 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 19 Jul 2018 22:45:23 +0000 (23:45 +0100)
80 files changed:
src/lib/active_captions.cc
src/lib/bitmap_caption.h [new file with mode: 0644]
src/lib/bitmap_text.h [deleted file]
src/lib/caption_content.cc [new file with mode: 0644]
src/lib/caption_content.h [new file with mode: 0644]
src/lib/caption_decoder.cc [new file with mode: 0644]
src/lib/caption_decoder.h [new file with mode: 0644]
src/lib/content.cc
src/lib/content.h
src/lib/content_caption.h [new file with mode: 0644]
src/lib/content_factory.cc
src/lib/content_text.h [deleted file]
src/lib/dcp_content.cc
src/lib/dcp_decoder.cc
src/lib/dcp_encoder.cc
src/lib/dcp_encoder.h
src/lib/dcp_subtitle_content.cc [new file with mode: 0644]
src/lib/dcp_subtitle_content.h [new file with mode: 0644]
src/lib/dcp_subtitle_decoder.cc [new file with mode: 0644]
src/lib/dcp_subtitle_decoder.h [new file with mode: 0644]
src/lib/dcp_text_content.cc [deleted file]
src/lib/dcp_text_content.h [deleted file]
src/lib/dcp_text_decoder.cc [deleted file]
src/lib/dcp_text_decoder.h [deleted file]
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/plain_text_file.cc [deleted file]
src/lib/plain_text_file.h [deleted file]
src/lib/player.cc
src/lib/player.h
src/lib/player_caption.h
src/lib/playlist.cc
src/lib/reel_writer.cc
src/lib/reel_writer.h
src/lib/text_caption_file.cc [new file with mode: 0644]
src/lib/text_caption_file.h [new file with mode: 0644]
src/lib/text_caption_file_content.cc
src/lib/text_caption_file_decoder.cc
src/lib/text_caption_file_decoder.h
src/lib/text_content.cc [deleted file]
src/lib/text_content.h [deleted file]
src/lib/text_decoder.cc [deleted file]
src/lib/text_decoder.h [deleted file]
src/lib/types.cc
src/lib/types.h
src/lib/writer.cc
src/lib/writer.h
src/lib/wscript
src/tools/dcpomatic.cc
src/tools/dcpomatic_player.cc
src/wx/caption_panel.cc
src/wx/content_panel.cc
src/wx/dcp_panel.cc
src/wx/fonts_dialog.cc
src/wx/paste_dialog.cc
src/wx/paste_dialog.h
src/wx/player_information.cc
src/wx/subtitle_appearance_dialog.cc
src/wx/subtitle_view.cc
src/wx/subtitle_view.h
src/wx/timeline.cc
src/wx/timeline_text_content_view.cc
src/wx/timing_panel.cc
test/dcp_subtitle_test.cc
test/ffmpeg_encoder_test.cc
test/import_dcp_test.cc
test/player_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_charset_test.cc
test/subtitle_reel_number_test.cc
test/subtitle_trim_test.cc
test/vf_kdm_test.cc

index 972095e37afbf66aa9c53528746dac769f52126b..d41270382c7cf08785c7c32f6b50d1296fa44c1d 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "active_captions.h"
 #include "piece.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include <boost/shared_ptr.hpp>
 #include <boost/weak_ptr.hpp>
 
@@ -47,7 +47,7 @@ ActiveCaptions::get_burnt (DCPTimePeriod period, bool always_burn_subtitles) con
                        continue;
                }
 
-               if (!piece->content->subtitle->use() || (!always_burn_subtitles && !piece->content->subtitle->burn())) {
+               if (!piece->content->caption->use() || (!always_burn_subtitles && !piece->content->caption->burn())) {
                        /* Not burning this piece */
                        continue;
                }
diff --git a/src/lib/bitmap_caption.h b/src/lib/bitmap_caption.h
new file mode 100644 (file)
index 0000000..8883272
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+    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/>.
+
+*/
+
+#ifndef DCPOMATIC_BITMAP_CAPTION_H
+#define DCPOMATIC_BITMAP_CAPTION_H
+
+#include "rect.h"
+#include <boost/shared_ptr.hpp>
+
+class Image;
+
+class BitmapCaption
+{
+public:
+       BitmapCaption (boost::shared_ptr<Image> i, dcpomatic::Rect<double> r)
+               : image (i)
+               , rectangle (r)
+       {}
+
+       boost::shared_ptr<Image> image;
+       /** Area that the subtitle covers on its corresponding video, expressed in
+        *  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 TextContent's offsets and
+        *  scale applied to it, depending on context.
+        */
+       dcpomatic::Rect<double> rectangle;
+};
+
+#endif
diff --git a/src/lib/bitmap_text.h b/src/lib/bitmap_text.h
deleted file mode 100644 (file)
index 64de768..0000000
+++ /dev/null
@@ -1,48 +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/>.
-
-*/
-
-#ifndef DCPOMATIC_BITMAP_TEXT_H
-#define DCPOMATIC_BITMAP_TEXT_H
-
-#include "rect.h"
-#include <boost/shared_ptr.hpp>
-
-class Image;
-
-class BitmapText
-{
-public:
-       BitmapText (boost::shared_ptr<Image> i, dcpomatic::Rect<double> r)
-               : image (i)
-               , rectangle (r)
-       {}
-
-       boost::shared_ptr<Image> image;
-       /** Area that the subtitle covers on its corresponding video, expressed in
-        *  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 TextContent's offsets and
-        *  scale applied to it, depending on context.
-        */
-       dcpomatic::Rect<double> rectangle;
-};
-
-#endif
diff --git a/src/lib/caption_content.cc b/src/lib/caption_content.cc
new file mode 100644 (file)
index 0000000..33e21bc
--- /dev/null
@@ -0,0 +1,528 @@
+/*
+    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 "caption_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 CaptionContentProperty::X_OFFSET = 500;
+int const CaptionContentProperty::Y_OFFSET = 501;
+int const CaptionContentProperty::X_SCALE = 502;
+int const CaptionContentProperty::Y_SCALE = 503;
+int const CaptionContentProperty::USE = 504;
+int const CaptionContentProperty::BURN = 505;
+int const CaptionContentProperty::LANGUAGE = 506;
+int const CaptionContentProperty::FONTS = 507;
+int const CaptionContentProperty::COLOUR = 508;
+int const CaptionContentProperty::EFFECT = 509;
+int const CaptionContentProperty::EFFECT_COLOUR = 510;
+int const CaptionContentProperty::LINE_SPACING = 511;
+int const CaptionContentProperty::FADE_IN = 512;
+int const CaptionContentProperty::FADE_OUT = 513;
+int const CaptionContentProperty::OUTLINE_WIDTH = 514;
+int const CaptionContentProperty::TYPE = 515;
+
+CaptionContent::CaptionContent (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)
+       , _type (CAPTION_OPEN)
+{
+
+}
+
+shared_ptr<CaptionContent>
+CaptionContent::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<CaptionContent> ();
+               }
+
+               /* 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<CaptionContent> ();
+       }
+
+       return shared_ptr<CaptionContent> (new CaptionContent (parent, node, version));
+}
+
+CaptionContent::CaptionContent (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))
+       , _type (CAPTION_OPEN)
+{
+       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 ();
+
+       _type = string_to_caption_type (node->optional_string_child("CaptionType").get_value_or("open"));
+}
+
+CaptionContent::CaptionContent (Content* parent, vector<shared_ptr<Content> > c)
+       : ContentPart (parent)
+{
+       shared_ptr<CaptionContent> ref = c[0]->caption;
+       DCPOMATIC_ASSERT (ref);
+       list<shared_ptr<Font> > ref_fonts = ref->fonts ();
+
+       for (size_t i = 1; i < c.size(); ++i) {
+
+               if (c[i]->caption->use() != ref->use()) {
+                       throw JoinError (_("Content to be joined must have the same 'use subtitles' setting."));
+               }
+
+               if (c[i]->caption->burn() != ref->burn()) {
+                       throw JoinError (_("Content to be joined must have the same 'burn subtitles' setting."));
+               }
+
+               if (c[i]->caption->x_offset() != ref->x_offset()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle X offset."));
+               }
+
+               if (c[i]->caption->y_offset() != ref->y_offset()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
+               }
+
+               if (c[i]->caption->x_scale() != ref->x_scale()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle X scale."));
+               }
+
+               if (c[i]->caption->y_scale() != ref->y_scale()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
+               }
+
+               if (c[i]->caption->line_spacing() != ref->line_spacing()) {
+                       throw JoinError (_("Content to be joined must have the same subtitle line spacing."));
+               }
+
+               if ((c[i]->caption->fade_in() != ref->fade_in()) || (c[i]->caption->fade_out() != ref->fade_out())) {
+                       throw JoinError (_("Content to be joined must have the same subtitle fades."));
+               }
+
+               if ((c[i]->caption->outline_width() != ref->outline_width())) {
+                       throw JoinError (_("Content to be joined must have the same outline width."));
+               }
+
+               list<shared_ptr<Font> > fonts = c[i]->caption->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
+CaptionContent::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"));
+       }
+
+       root->add_child("CaptionType")->add_child_text (caption_type_to_string(_type));
+}
+
+string
+CaptionContent::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
+CaptionContent::add_font (shared_ptr<Font> font)
+{
+       _fonts.push_back (font);
+       connect_to_fonts ();
+}
+
+void
+CaptionContent::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 (&CaptionContent::font_changed, this)));
+       }
+}
+
+void
+CaptionContent::font_changed ()
+{
+       _parent->signal_changed (CaptionContentProperty::FONTS);
+}
+
+void
+CaptionContent::set_colour (dcp::Colour colour)
+{
+       maybe_set (_colour, colour, CaptionContentProperty::COLOUR);
+}
+
+void
+CaptionContent::unset_colour ()
+{
+       maybe_set (_colour, optional<dcp::Colour>(), CaptionContentProperty::COLOUR);
+}
+
+void
+CaptionContent::set_effect (dcp::Effect e)
+{
+       maybe_set (_effect, e, CaptionContentProperty::EFFECT);
+}
+
+void
+CaptionContent::unset_effect ()
+{
+       maybe_set (_effect, optional<dcp::Effect>(), CaptionContentProperty::EFFECT);
+}
+
+void
+CaptionContent::set_effect_colour (dcp::Colour colour)
+{
+       maybe_set (_effect_colour, colour, CaptionContentProperty::EFFECT_COLOUR);
+}
+
+void
+CaptionContent::unset_effect_colour ()
+{
+       maybe_set (_effect_colour, optional<dcp::Colour>(), CaptionContentProperty::EFFECT_COLOUR);
+}
+
+void
+CaptionContent::set_use (bool u)
+{
+       maybe_set (_use, u, CaptionContentProperty::USE);
+}
+
+void
+CaptionContent::set_burn (bool b)
+{
+       maybe_set (_burn, b, CaptionContentProperty::BURN);
+}
+
+void
+CaptionContent::set_x_offset (double o)
+{
+       maybe_set (_x_offset, o, CaptionContentProperty::X_OFFSET);
+}
+
+void
+CaptionContent::set_y_offset (double o)
+{
+       maybe_set (_y_offset, o, CaptionContentProperty::Y_OFFSET);
+}
+
+void
+CaptionContent::set_x_scale (double s)
+{
+       maybe_set (_x_scale, s, CaptionContentProperty::X_SCALE);
+}
+
+void
+CaptionContent::set_y_scale (double s)
+{
+       maybe_set (_y_scale, s, CaptionContentProperty::Y_SCALE);
+}
+
+void
+CaptionContent::set_language (string language)
+{
+       maybe_set (_language, language, CaptionContentProperty::LANGUAGE);
+}
+
+void
+CaptionContent::set_line_spacing (double s)
+{
+       maybe_set (_line_spacing, s, CaptionContentProperty::LINE_SPACING);
+}
+
+void
+CaptionContent::set_fade_in (ContentTime t)
+{
+       maybe_set (_fade_in, t, CaptionContentProperty::FADE_IN);
+}
+
+void
+CaptionContent::unset_fade_in ()
+{
+       maybe_set (_fade_in, optional<ContentTime>(), CaptionContentProperty::FADE_IN);
+}
+
+void
+CaptionContent::set_fade_out (ContentTime t)
+{
+       maybe_set (_fade_out, t, CaptionContentProperty::FADE_OUT);
+}
+
+void
+CaptionContent::unset_fade_out ()
+{
+       maybe_set (_fade_out, optional<ContentTime>(), CaptionContentProperty::FADE_OUT);
+}
+
+void
+CaptionContent::set_type (CaptionType type)
+{
+       maybe_set (_type, type, CaptionContentProperty::TYPE);
+}
+
+void
+CaptionContent::set_outline_width (int w)
+{
+       maybe_set (_outline_width, w, CaptionContentProperty::OUTLINE_WIDTH);
+}
+
+void
+CaptionContent::take_settings_from (shared_ptr<const CaptionContent> 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, CaptionContentProperty::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/caption_content.h b/src/lib/caption_content.h
new file mode 100644 (file)
index 0000000..25f7a1d
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+    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_CAPTION_CONTENT_H
+#define DCPOMATIC_CAPTION_CONTENT_H
+
+#include "content_part.h"
+#include <libcxml/cxml.h>
+#include <dcp/types.h>
+#include <boost/signals2.hpp>
+
+class Font;
+
+class CaptionContentProperty
+{
+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;
+       static int const TYPE;
+};
+
+/** @class CaptionContent
+ *  @brief Description of how some text content should be presented.
+ *
+ *  There are `bitmap' subtitles and `plain' subtitles (plain text),
+ *  and not all of the settings in this class correspond to both types.
+ */
+class CaptionContent : public ContentPart
+{
+public:
+       explicit CaptionContent (Content* parent);
+       CaptionContent (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 CaptionContent> 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 ();
+       void set_type (CaptionType type);
+
+       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;
+       }
+
+       CaptionType type () const {
+               boost::mutex::scoped_lock lm (_mutex);
+               return _type;
+       }
+
+       static boost::shared_ptr<CaptionContent> 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;
+
+       CaptionContent (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;
+       CaptionType _type;
+};
+
+#endif
diff --git a/src/lib/caption_decoder.cc b/src/lib/caption_decoder.cc
new file mode 100644 (file)
index 0000000..1a22210
--- /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 "caption_decoder.h"
+#include "caption_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;
+
+CaptionDecoder::CaptionDecoder (
+       Decoder* parent,
+       shared_ptr<const CaptionContent> 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
+CaptionDecoder::emit_bitmap_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
+{
+       BitmapStart (ContentBitmapCaption (from, _content->type(), image, rect));
+       _position = from;
+}
+
+void
+CaptionDecoder::emit_plain_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));
+               }
+       }
+
+       PlainStart (ContentTextCaption (from, _content->type(), s));
+       _position = from;
+}
+
+void
+CaptionDecoder::emit_plain_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_plain_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_plain_start (from, out);
+}
+
+void
+CaptionDecoder::emit_stop (ContentTime to)
+{
+       Stop (to, _content->type());
+}
+
+void
+CaptionDecoder::emit_plain (ContentTimePeriod period, list<dcp::SubtitleString> s)
+{
+       emit_plain_start (period.from, s);
+       emit_stop (period.to);
+}
+
+void
+CaptionDecoder::emit_plain (ContentTimePeriod period, sub::Subtitle const & s)
+{
+       emit_plain_start (period.from, s);
+       emit_stop (period.to);
+}
+
+void
+CaptionDecoder::seek ()
+{
+       _position = ContentTime ();
+}
diff --git a/src/lib/caption_decoder.h b/src/lib/caption_decoder.h
new file mode 100644 (file)
index 0000000..d555446
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+    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_CAPTION_DECODER_H
+#define DCPOMATIC_CAPTION_DECODER_H
+
+#include "decoder.h"
+#include "rect.h"
+#include "types.h"
+#include "content_caption.h"
+#include "decoder_part.h"
+#include <dcp/subtitle_string.h>
+#include <boost/signals2.hpp>
+
+namespace sub {
+       class Subtitle;
+}
+
+class Image;
+
+class CaptionDecoder : public DecoderPart
+{
+public:
+       CaptionDecoder (
+               Decoder* parent,
+               boost::shared_ptr<const CaptionContent>,
+               boost::shared_ptr<Log> log,
+               ContentTime first
+               );
+
+       ContentTime position () const {
+               return _position;
+       }
+
+       void emit_bitmap_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
+       void emit_plain_start (ContentTime from, std::list<dcp::SubtitleString> s);
+       void emit_plain_start (ContentTime from, sub::Subtitle const & subtitle);
+       void emit_plain (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
+       void emit_plain (ContentTimePeriod period, sub::Subtitle const & subtitle);
+       void emit_stop (ContentTime to);
+
+       void seek ();
+
+       boost::shared_ptr<const CaptionContent> content () const {
+               return _content;
+       }
+
+       boost::signals2::signal<void (ContentBitmapCaption)> BitmapStart;
+       boost::signals2::signal<void (ContentTextCaption)> PlainStart;
+       boost::signals2::signal<void (ContentTime, CaptionType)> Stop;
+
+private:
+       boost::shared_ptr<const CaptionContent> _content;
+       ContentTime _position;
+};
+
+#endif
index 1a8bc9eb20aabe80a9c395121d45d61ff4ea555e..af4c6c7018d5d8b80aaa4af499ba4f5964bda8a2 100644 (file)
@@ -27,7 +27,7 @@
 #include "content_factory.h"
 #include "video_content.h"
 #include "audio_content.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include "exceptions.h"
 #include "film.h"
 #include "job.h"
@@ -436,7 +436,7 @@ Content::take_settings_from (shared_ptr<const Content> c)
        if (audio && c->audio) {
                audio->take_settings_from (c->audio);
        }
-       if (subtitle && c->subtitle) {
-               subtitle->take_settings_from (c->subtitle);
+       if (caption && c->caption) {
+               caption->take_settings_from (c->caption);
        }
 }
index 63d03fd713121cdf3fadebe17390158e32fa9284..7ff20e96cba4a335f219d4aed2eb5748a98951ae 100644 (file)
@@ -182,7 +182,7 @@ public:
 
        boost::shared_ptr<VideoContent> video;
        boost::shared_ptr<AudioContent> audio;
-       boost::shared_ptr<TextContent> subtitle;
+       boost::shared_ptr<CaptionContent> caption;
 
        void signal_changed (int);
 
diff --git a/src/lib/content_caption.h b/src/lib/content_caption.h
new file mode 100644 (file)
index 0000000..ad83fcb
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+    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/>.
+
+*/
+
+#ifndef DCPOMATIC_CONTENT_TEXT_H
+#define DCPOMATIC_CONTENT_TEXT_H
+
+#include "dcpomatic_time.h"
+#include "rect.h"
+#include "types.h"
+#include "bitmap_caption.h"
+#include <dcp/subtitle_string.h>
+#include <list>
+
+class Image;
+
+class ContentCaption
+{
+public:
+       explicit ContentCaption (ContentTime f, CaptionType t)
+               : _from (f)
+               , _type (t)
+       {}
+
+       ContentTime from () const {
+               return _from;
+       }
+
+       CaptionType type () const {
+               return _type;
+       }
+
+private:
+       ContentTime _from;
+       CaptionType _type;
+};
+
+class ContentBitmapCaption : public ContentCaption
+{
+public:
+       ContentBitmapCaption (ContentTime f, CaptionType type, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
+               : ContentCaption (f, type)
+               , sub (im, r)
+       {}
+
+       /* Our text, with its rectangle unmodified by any offsets or scales that the content specifies */
+       BitmapCaption sub;
+};
+
+/** A text caption.  We store the time period separately (as well as in the dcp::SubtitleStrings)
+ *  as the dcp::SubtitleString timings are sometimes quite heavily quantised and this causes problems
+ *  when we want to compare the quantised periods to the unquantised ones.
+ */
+class ContentTextCaption : public ContentCaption
+{
+public:
+       ContentTextCaption (ContentTime f, CaptionType type, std::list<dcp::SubtitleString> s)
+               : ContentCaption (f, type)
+               , subs (s)
+       {}
+
+       std::list<dcp::SubtitleString> subs;
+};
+
+#endif
index 9429f1c469b86950517907fe96f34a92e3eaf8fe..8c473b7bc27e524fb0ca9f6134fe1bd3dec3522c 100644 (file)
@@ -28,7 +28,7 @@
 #include "atmos_mxf_content.h"
 #include "text_caption_file_content.h"
 #include "dcp_content.h"
-#include "dcp_text_content.h"
+#include "dcp_subtitle_content.h"
 #include "util.h"
 #include "ffmpeg_audio_stream.h"
 #include "video_mxf_content.h"
@@ -92,7 +92,7 @@ content_factory (shared_ptr<const Film> film, cxml::NodePtr node, int version, l
        } else if (type == "DCP") {
                content.reset (new DCPContent (film, node, version));
        } else if (type == "DCPSubtitle") {
-               content.reset (new DCPTextContent (film, node, version));
+               content.reset (new DCPSubtitleContent (film, node, version));
        } else if (type == "VideoMXF") {
                content.reset (new VideoMXFContent (film, node, version));
        } else if (type == "AtmosMXF") {
@@ -217,9 +217,9 @@ content_factory (shared_ptr<const Film> film, boost::filesystem::path path)
                        if (doc.root_name() == "DCinemaSecurityMessage") {
                                throw KDMAsContentError ();
                        }
-                       single.reset (new DCPTextContent (film, path));
+                       single.reset (new DCPSubtitleContent (film, path));
                } else if (ext == ".mxf" && dcp::SMPTESubtitleAsset::valid_mxf (path)) {
-                       single.reset (new DCPTextContent (film, path));
+                       single.reset (new DCPSubtitleContent (film, path));
                } else if (ext == ".mxf" && VideoMXFContent::valid_mxf (path)) {
                        single.reset (new VideoMXFContent (film, path));
                } else if (ext == ".mxf" && AtmosMXFContent::valid_mxf (path)) {
diff --git a/src/lib/content_text.h b/src/lib/content_text.h
deleted file mode 100644 (file)
index 1b550c9..0000000
+++ /dev/null
@@ -1,81 +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/>.
-
-*/
-
-#ifndef DCPOMATIC_CONTENT_TEXT_H
-#define DCPOMATIC_CONTENT_TEXT_H
-
-#include "dcpomatic_time.h"
-#include "rect.h"
-#include "types.h"
-#include "bitmap_text.h"
-#include <dcp/subtitle_string.h>
-#include <list>
-
-class Image;
-
-class ContentText
-{
-public:
-       explicit ContentText (ContentTime f, TextType t)
-               : _from (f)
-               , _type (t)
-       {}
-
-       ContentTime from () const {
-               return _from;
-       }
-
-       TextType type () const {
-               return _type;
-       }
-
-private:
-       ContentTime _from;
-       TextType _type;
-};
-
-class ContentBitmapCaption : public ContentText
-{
-public:
-       ContentBitmapCaption (ContentTime f, TextType type, boost::shared_ptr<Image> im, dcpomatic::Rect<double> r)
-               : ContentText (f, type)
-               , sub (im, r)
-       {}
-
-       /* Our text, with its rectangle unmodified by any offsets or scales that the content specifies */
-       BitmapText sub;
-};
-
-/** A text caption.  We store the time period separately (as well as in the dcp::SubtitleStrings)
- *  as the dcp::SubtitleString timings are sometimes quite heavily quantised and this causes problems
- *  when we want to compare the quantised periods to the unquantised ones.
- */
-class ContentTextCaption : public ContentText
-{
-public:
-       ContentTextCaption (ContentTime f, TextType type, std::list<dcp::SubtitleString> s)
-               : ContentText (f, type)
-               , subs (s)
-       {}
-
-       std::list<dcp::SubtitleString> subs;
-};
-
-#endif
index d4891ad457849a4db38b2a94a7540abe23b9ce03..e02eb7bd90ea6bc66097defc62e88d6352b21d41 100644 (file)
@@ -28,7 +28,7 @@
 #include "overlaps.h"
 #include "compose.hpp"
 #include "dcp_decoder.h"
-#include "text_content.h"
+#include "caption_content.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);
-       subtitle = TextContent::from_xml (this, node, version);
+       caption = CaptionContent::from_xml (this, node, version);
 
        if (video && audio) {
                audio->set_stream (
@@ -143,7 +143,7 @@ DCPContent::examine (shared_ptr<Job> job)
        bool const needed_assets = needs_assets ();
        bool const needed_kdm = needs_kdm ();
        string const old_name = name ();
-       bool had_subtitles = static_cast<bool> (subtitle);
+       bool had_subtitles = static_cast<bool> (caption);
 
        if (job) {
                job->set_progress_unknown ();
@@ -179,11 +179,11 @@ DCPContent::examine (shared_ptr<Job> job)
                boost::mutex::scoped_lock lm (_mutex);
                _name = examiner->name ();
                if (examiner->has_subtitles ()) {
-                       subtitle.reset (new TextContent (this));
+                       caption.reset (new CaptionContent (this));
                } else {
-                       subtitle.reset ();
+                       caption.reset ();
                }
-               has_subtitles = static_cast<bool> (subtitle);
+               has_subtitles = static_cast<bool> (caption);
                _encrypted = examiner->encrypted ();
                _needs_assets = examiner->needs_assets ();
                _kdm_valid = examiner->kdm_valid ();
@@ -254,8 +254,8 @@ DCPContent::as_xml (xmlpp::Node* node, bool with_paths) const
                audio->stream()->mapping().as_xml (node->add_child("AudioMapping"));
        }
 
-       if (subtitle) {
-               subtitle->as_xml (node);
+       if (caption) {
+               caption->as_xml (node);
        }
 
        boost::mutex::scoped_lock lm (_mutex);
@@ -309,8 +309,8 @@ DCPContent::identifier () const
                s += video->identifier() + "_";
        }
 
-       if (subtitle) {
-               s += subtitle->identifier () + " ";
+       if (caption) {
+               s += caption->identifier () + " ";
        }
 
        s += string (_reference_video ? "1" : "0") + string (_reference_subtitle ? "1" : "0");
@@ -584,7 +584,7 @@ DCPContent::can_reference_subtitle (string& why_not) const
         }
 
        /// TRANSLATORS: this string will follow "Cannot reference this DCP: "
-       return can_reference (bind (&Content::subtitle, _1), _("it overlaps other subtitle content; remove the other content."), why_not);
+       return can_reference (bind (&Content::caption, _1), _("it overlaps other caption content; remove the other content."), why_not);
 }
 
 void
index 6a9de841d51f078bc41c6962b0230a473ce42876..cc415629b2c3654a698ed470708d07e6f6cf5839 100644 (file)
@@ -24,7 +24,7 @@
 #include "video_decoder.h"
 #include "audio_decoder.h"
 #include "j2k_image_proxy.h"
-#include "text_decoder.h"
+#include "caption_decoder.h"
 #include "image.h"
 #include "config.h"
 #include <dcp/dcp.h>
@@ -62,9 +62,9 @@ DCPDecoder::DCPDecoder (shared_ptr<const DCPContent> c, shared_ptr<Log> log, boo
        if (c->audio) {
                audio.reset (new AudioDecoder (this, c->audio, log, fast));
        }
-       if (c->subtitle) {
+       if (c->caption) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
-               subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
+               caption.reset (new CaptionDecoder (this, c->caption, log, ContentTime()));
        }
 
        list<shared_ptr<dcp::CPL> > cpl_list = cpls ();
@@ -209,7 +209,7 @@ DCPDecoder::pass_subtitles (ContentTime next)
                        if (is) {
                                list<dcp::SubtitleString> s;
                                s.push_back (*is);
-                               subtitle->emit_plain (
+                               caption->emit_plain (
                                        ContentTimePeriod (
                                                ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->in().as_seconds ()),
                                                ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->out().as_seconds ())
index 9766aad337e0cea449bc7ba7c262bf7f82ae7ca4..541c23b6cb4576c86009014014b5b1539df59bfe 100644 (file)
@@ -35,7 +35,7 @@
 #include "writer.h"
 #include "compose.hpp"
 #include "referenced_reel_asset.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include "player_video.h"
 #include <boost/signals2.hpp>
 #include <boost/foreach.hpp>
@@ -61,10 +61,10 @@ DCPEncoder::DCPEncoder (shared_ptr<const Film> film, weak_ptr<Job> job)
 {
        _player_video_connection = _player->Video.connect (bind (&DCPEncoder::video, this, _1, _2));
        _player_audio_connection = _player->Audio.connect (bind (&DCPEncoder::audio, this, _1, _2));
-       _player_text_connection = _player->Text.connect (bind (&DCPEncoder::text, this, _1, _2, _3));
+       _player_caption_connection = _player->Caption.connect (bind (&DCPEncoder::caption, this, _1, _2, _3));
 
        BOOST_FOREACH (shared_ptr<const Content> c, film->content ()) {
-               if (c->subtitle && c->subtitle->use() && !c->subtitle->burn()) {
+               if (c->caption && c->caption->use() && !c->caption->burn()) {
                        _non_burnt_subtitles = true;
                }
        }
@@ -75,7 +75,7 @@ DCPEncoder::~DCPEncoder ()
        /* We must stop receiving more video data before we die */
        _player_video_connection.release ();
        _player_audio_connection.release ();
-       _player_text_connection.release ();
+       _player_caption_connection.release ();
 }
 
 void
@@ -141,9 +141,9 @@ DCPEncoder::audio (shared_ptr<AudioBuffers> data, DCPTime time)
 }
 
 void
-DCPEncoder::text (PlayerCaption data, TextType type, DCPTimePeriod period)
+DCPEncoder::caption (PlayerCaption data, CaptionType type, DCPTimePeriod period)
 {
-       if (type == TEXT_CLOSED_CAPTION || _non_burnt_subtitles) {
+       if (type == CAPTION_CLOSED || _non_burnt_subtitles) {
                _writer->write (data, type, period);
        }
 }
index 850ead6568f655df4613fc2bb2986b2356d22c96..9808987c3ce61eee7bdb9b34db8eead74590e7d1 100644 (file)
@@ -52,7 +52,7 @@ private:
 
        void video (boost::shared_ptr<PlayerVideo>, DCPTime);
        void audio (boost::shared_ptr<AudioBuffers>, DCPTime);
-       void text (PlayerCaption, TextType, DCPTimePeriod);
+       void caption (PlayerCaption, CaptionType, DCPTimePeriod);
 
        boost::shared_ptr<Writer> _writer;
        boost::shared_ptr<J2KEncoder> _j2k_encoder;
@@ -61,5 +61,5 @@ private:
 
        boost::signals2::scoped_connection _player_video_connection;
        boost::signals2::scoped_connection _player_audio_connection;
-       boost::signals2::scoped_connection _player_text_connection;
+       boost::signals2::scoped_connection _player_caption_connection;
 };
diff --git a/src/lib/dcp_subtitle_content.cc b/src/lib/dcp_subtitle_content.cc
new file mode 100644 (file)
index 0000000..17477cf
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+    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 "font.h"
+#include "dcp_subtitle_content.h"
+#include "film.h"
+#include "caption_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)
+{
+       caption.reset (new CaptionContent (this));
+}
+
+DCPSubtitleContent::DCPSubtitleContent (shared_ptr<const Film> film, cxml::ConstNodePtr node, int version)
+       : Content (film, node)
+       , _length (node->number_child<ContentTime::Type> ("Length"))
+{
+       caption = CaptionContent::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 */
+       caption->set_use (true);
+
+       if (iop) {
+               caption->set_language (iop->language ());
+       } else if (smpte) {
+               caption->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 ()) {
+               caption->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 (caption) {
+               caption->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
new file mode 100644 (file)
index 0000000..36945ad
--- /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 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
new file mode 100644 (file)
index 0000000..c7a9a86
--- /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_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;
+       }
+       caption.reset (new CaptionDecoder (this, content->caption, 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 plain_text() call otherwise the
+          CaptionDecoder 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 */
+       }
+
+       caption->emit_plain (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
new file mode 100644 (file)
index 0000000..ef4dad3
--- /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 "caption_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
deleted file mode 100644 (file)
index 9e7524b..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_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
deleted file mode 100644 (file)
index 894cc03..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 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
deleted file mode 100644 (file)
index 168bfa5..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_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 plain_text() 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_plain (p, s);
-       return false;
-}
-
-ContentTimePeriod
-DCPTextDecoder::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_text_decoder.h b/src/lib/dcp_text_decoder.h
deleted file mode 100644 (file)
index f1b51b8..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 "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 e7e6b8620e9332e0dc51f79f8c5d4e743f884758..70eb5b61a3f34b4fad30cc22f82683f448789751 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -21,7 +21,7 @@
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
-#include "text_decoder.h"
+#include "caption_decoder.h"
 #include <boost/optional.hpp>
 #include <iostream>
 
@@ -42,8 +42,8 @@ Decoder::position () const
                pos = audio->position();
        }
 
-       if (subtitle && !subtitle->ignore() && (!pos || subtitle->position() < *pos)) {
-               pos = subtitle->position();
+       if (caption && !caption->ignore() && (!pos || caption->position() < *pos)) {
+               pos = caption->position();
        }
 
        return pos.get_value_or(ContentTime());
@@ -58,7 +58,7 @@ Decoder::seek (ContentTime, bool)
        if (audio) {
                audio->seek ();
        }
-       if (subtitle) {
-               subtitle->seek ();
+       if (caption) {
+               caption->seek ();
        }
 }
index 27f0b114144187e02acdc882bef93a0c8dfdb82c..c3b330cfbcd49bdf376cba575ca52c7e5ab2d258 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2012-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -32,7 +32,7 @@
 class Decoded;
 class VideoDecoder;
 class AudioDecoder;
-class TextDecoder;
+class CaptionDecoder;
 class DecoderPart;
 
 /** @class Decoder.
@@ -45,7 +45,7 @@ public:
 
        boost::shared_ptr<VideoDecoder> video;
        boost::shared_ptr<AudioDecoder> audio;
-       boost::shared_ptr<TextDecoder> subtitle;
+       boost::shared_ptr<CaptionDecoder> caption;
 
        /** 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 3d4ce8a7bff21ba66dd73579f8ca357dc8459cc0..bb3bdb13e3325db1cf65072dcd8987a98fb9dc8c 100644 (file)
@@ -26,8 +26,8 @@
 #include "image_decoder.h"
 #include "text_caption_file_content.h"
 #include "text_caption_file_decoder.h"
-#include "dcp_text_content.h"
-#include "dcp_text_decoder.h"
+#include "dcp_subtitle_content.h"
+#include "dcp_subtitle_decoder.h"
 #include "video_mxf_content.h"
 #include "video_mxf_decoder.h"
 #include <boost/foreach.hpp>
@@ -59,9 +59,9 @@ decoder_factory (shared_ptr<const Content> content, shared_ptr<Log> log, bool fa
                return shared_ptr<Decoder> (new TextCaptionFileDecoder (rc, log));
        }
 
-       shared_ptr<const DCPTextContent> dsc = dynamic_pointer_cast<const DCPTextContent> (content);
+       shared_ptr<const DCPSubtitleContent> dsc = dynamic_pointer_cast<const DCPSubtitleContent> (content);
        if (dsc) {
-               return shared_ptr<Decoder> (new DCPTextDecoder (dsc, log));
+               return shared_ptr<Decoder> (new DCPSubtitleDecoder (dsc, log));
        }
 
        shared_ptr<const VideoMXFContent> vmc = dynamic_pointer_cast<const VideoMXFContent> (content);
index e18977944648fc1faff37e83987d8018a63fe473..dd4ed7063f91199c6232dc4d3f684059c1c11312 100644 (file)
@@ -32,7 +32,7 @@
 #include "log.h"
 #include "exceptions.h"
 #include "frame_rate_change.h"
-#include "text_content.h"
+#include "caption_content.h"
 #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);
-       subtitle = TextContent::from_xml (this, node, version);
+       caption = CaptionContent::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) {
@@ -135,12 +135,12 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Con
 
        bool need_video = false;
        bool need_audio = false;
-       bool need_subtitle = false;
+       bool need_caption = false;
 
        if (i != c.end ()) {
                need_video = static_cast<bool> ((*i)->video);
                need_audio = static_cast<bool> ((*i)->audio);
-               need_subtitle = static_cast<bool> ((*i)->subtitle);
+               need_caption = static_cast<bool> ((*i)->caption);
        }
 
        while (i != c.end ()) {
@@ -150,8 +150,8 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Con
                if (need_audio != static_cast<bool> ((*i)->audio)) {
                        throw JoinError (_("Content to be joined must all have or not have audio"));
                }
-               if (need_subtitle != static_cast<bool> ((*i)->subtitle)) {
-                       throw JoinError (_("Content to be joined must all have or not have subtitles"));
+               if (need_caption != static_cast<bool> ((*i)->caption)) {
+                       throw JoinError (_("Content to be joined must all have or not have captions"));
                }
                ++i;
        }
@@ -162,8 +162,8 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Con
        if (need_audio) {
                audio.reset (new AudioContent (this, c));
        }
-       if (need_subtitle) {
-               subtitle.reset (new TextContent (this, c));
+       if (need_caption) {
+               caption.reset (new CaptionContent (this, c));
        }
 
        shared_ptr<FFmpegContent> ref = dynamic_pointer_cast<FFmpegContent> (c[0]);
@@ -171,7 +171,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> film, vector<shared_ptr<Con
 
        for (size_t i = 0; i < c.size(); ++i) {
                shared_ptr<FFmpegContent> fc = dynamic_pointer_cast<FFmpegContent> (c[i]);
-               if (fc->subtitle && fc->subtitle->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
+               if (fc->caption && fc->caption->use() && *(fc->_subtitle_stream.get()) != *(ref->_subtitle_stream.get())) {
                        throw JoinError (_("Content to be joined must use the same subtitle stream."));
                }
        }
@@ -209,8 +209,8 @@ FFmpegContent::as_xml (xmlpp::Node* node, bool with_paths) const
                }
        }
 
-       if (subtitle) {
-               subtitle->as_xml (node);
+       if (caption) {
+               caption->as_xml (node);
        }
 
        boost::mutex::scoped_lock lm (_mutex);
@@ -303,7 +303,7 @@ FFmpegContent::examine (shared_ptr<Job> job)
 
                _subtitle_streams = examiner->subtitle_streams ();
                if (!_subtitle_streams.empty ()) {
-                       subtitle.reset (new TextContent (this));
+                       caption.reset (new CaptionContent (this));
                        _subtitle_stream = _subtitle_streams.front ();
                }
 
@@ -426,8 +426,8 @@ FFmpegContent::identifier () const
                s += "_" + video->identifier();
        }
 
-       if (subtitle && subtitle->use() && subtitle->burn()) {
-               s += "_" + subtitle->identifier();
+       if (caption && caption->use() && caption->burn()) {
+               s += "_" + caption->identifier();
        }
 
        boost::mutex::scoped_lock lm (_mutex);
index 909a9d443d1383ebca4179554fa9745c12e5acfb..9478d8816c455ef47104b003c0638b805ad39e45 100644 (file)
@@ -28,7 +28,7 @@
 #include "util.h"
 #include "log.h"
 #include "ffmpeg_decoder.h"
-#include "text_decoder.h"
+#include "caption_decoder.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 "text_content.h"
+#include "caption_content.h"
 #include "audio_content.h"
 #include <dcp/subtitle_string.h>
 #include <sub/ssa_reader.h>
@@ -97,9 +97,9 @@ FFmpegDecoder::FFmpegDecoder (shared_ptr<const FFmpegContent> c, shared_ptr<Log>
                audio.reset (new AudioDecoder (this, c->audio, log, fast));
        }
 
-       if (c->subtitle) {
+       if (c->caption) {
                /* XXX: this time here should be the time of the first subtitle, not 0 */
-               subtitle.reset (new TextDecoder (this, c->subtitle, log, ContentTime()));
+               caption.reset (new CaptionDecoder (this, c->caption, log, ContentTime()));
        }
 
        _next_time.resize (_format_context->nb_streams);
@@ -184,7 +184,7 @@ FFmpegDecoder::pass ()
 
        if (_video_stream && si == _video_stream.get() && !video->ignore()) {
                decode_video_packet ();
-       } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index(_format_context, si) && !subtitle->ignore()) {
+       } else if (fc->subtitle_stream() && fc->subtitle_stream()->uses_index(_format_context, si) && !caption->ignore()) {
                decode_subtitle_packet ();
        } else {
                decode_audio_packet ();
@@ -549,9 +549,9 @@ FFmpegDecoder::decode_subtitle_packet ()
        /* Stop any current subtitle, either at the time it was supposed to stop, or now if now is sooner */
        if (_have_current_subtitle) {
                if (_current_subtitle_to) {
-                       subtitle->emit_stop (min(*_current_subtitle_to, subtitle_period(sub).from + _pts_offset));
+                       caption->emit_stop (min(*_current_subtitle_to, subtitle_period(sub).from + _pts_offset));
                } else {
-                       subtitle->emit_stop (subtitle_period(sub).from + _pts_offset);
+                       caption->emit_stop (subtitle_period(sub).from + _pts_offset);
                }
                _have_current_subtitle = false;
        }
@@ -593,7 +593,7 @@ FFmpegDecoder::decode_subtitle_packet ()
        }
 
        if (_current_subtitle_to) {
-               subtitle->emit_stop (*_current_subtitle_to);
+               caption->emit_stop (*_current_subtitle_to);
        }
 
        avsubtitle_free (&sub);
@@ -669,7 +669,7 @@ FFmpegDecoder::decode_bitmap_subtitle (AVSubtitleRect const * rect, ContentTime
                static_cast<double> (rect->h) / target_height
                );
 
-       subtitle->emit_bitmap_start (from, image, scaled_rect);
+       caption->emit_bitmap_start (from, image, scaled_rect);
 }
 
 void
@@ -702,6 +702,6 @@ FFmpegDecoder::decode_ass_subtitle (string ass, ContentTime from)
                );
 
        BOOST_FOREACH (sub::Subtitle const & i, sub::collect<list<sub::Subtitle> > (raw)) {
-               subtitle->emit_plain_start (from, i);
+               caption->emit_plain_start (from, i);
        }
 }
index 0be1ddd7b71a19161c44f6957f63c5a3aae23213..f6941c1c7aea3cc2c01b49fa1bbe8d5286c50ee6 100644 (file)
@@ -46,7 +46,7 @@
 #include "screen.h"
 #include "audio_content.h"
 #include "video_content.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include "ffmpeg_content.h"
 #include "dcp_content.h"
 #include "screen_kdm.h"
@@ -696,11 +696,11 @@ Film::isdcf_name (bool if_created_now) const
 
                        bool burnt_in = true;
                        BOOST_FOREACH (shared_ptr<Content> i, content ()) {
-                               if (!i->subtitle) {
+                               if (!i->caption) {
                                        continue;
                                }
 
-                               if (i->subtitle->use() && !i->subtitle->burn()) {
+                               if (i->caption->use() && !i->caption->burn()) {
                                        burnt_in = false;
                                }
                        }
@@ -1081,7 +1081,7 @@ Film::add_content (shared_ptr<Content> c)
        /* Add {video,subtitle} content after any existing {video,subtitle} content */
        if (c->video) {
                c->set_position (_playlist->video_end ());
-       } else if (c->subtitle) {
+       } else if (c->caption) {
                c->set_position (_playlist->subtitle_end ());
        }
 
@@ -1371,8 +1371,8 @@ Film::subtitle_language () const
 
        ContentList cl = content ();
        BOOST_FOREACH (shared_ptr<Content>& c, cl) {
-               if (c->subtitle) {
-                       languages.insert (c->subtitle->language ());
+               if (c->caption) {
+                       languages.insert (c->caption->language ());
                }
        }
 
index d29002ad56273e8fb51f94b61a29d2ffa5ee9881..eb3ea1d02c542752e277aff62f3258d4c6e2a475 100644 (file)
@@ -23,7 +23,7 @@
 #include "film.h"
 #include "content.h"
 #include "video_content.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include "audio_processor.h"
 #include "font.h"
 #include "ratio.h"
@@ -56,8 +56,8 @@ get_hints (shared_ptr<const Film> film)
        bool big_font_files = false;
        if (film->interop ()) {
                BOOST_FOREACH (shared_ptr<Content> i, content) {
-                       if (i->subtitle) {
-                               BOOST_FOREACH (shared_ptr<Font> j, i->subtitle->fonts ()) {
+                       if (i->caption) {
+                               BOOST_FOREACH (shared_ptr<Font> j, i->caption->fonts ()) {
                                        for (int k = 0; k < FontFiles::VARIANTS; ++k) {
                                                optional<boost::filesystem::path> const p = j->file (static_cast<FontFiles::Variant> (k));
                                                if (p && boost::filesystem::file_size (p.get()) >= (640 * 1024)) {
diff --git a/src/lib/plain_text_file.cc b/src/lib/plain_text_file.cc
deleted file mode 100644 (file)
index 666953c..0000000
+++ /dev/null
@@ -1,116 +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 "plain_text_file.h"
-#include "cross.h"
-#include "exceptions.h"
-#include "text_caption_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 boost::optional;
-using dcp::Data;
-
-TextCaptionFile::TextCaptionFile (shared_ptr<const TextCaptionFileContent> 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);
-
-       /* Fix OS X line endings */
-       size_t utf8_len = strlen (utf8.get ());
-       for (size_t i = 0; i < utf8_len; ++i) {
-               if (utf8[i] == '\r' && ((i == utf8_len - 1) || utf8[i + 1] != '\n')) {
-                       utf8[i] = '\n';
-               }
-       }
-
-       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;
-}
-
-/** @return time of first subtitle, if there is one */
-optional<ContentTime>
-TextCaptionFile::first () const
-{
-       if (_subtitles.empty()) {
-               return optional<ContentTime>();
-       }
-
-       return ContentTime::from_seconds(_subtitles[0].from.all_as_seconds());
-}
-
-ContentTime
-TextCaptionFile::length () const
-{
-       if (_subtitles.empty ()) {
-               return ContentTime ();
-       }
-
-       return ContentTime::from_seconds (_subtitles.back().to.all_as_seconds ());
-}
diff --git a/src/lib/plain_text_file.h b/src/lib/plain_text_file.h
deleted file mode 100644 (file)
index 8c74d9e..0000000
+++ /dev/null
@@ -1,53 +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/>.
-
-*/
-
-#ifndef DCPOMATIC_PLAIN_TEXT_FILE_H
-#define DCPOMATIC_PLAIN_TEXT_FILE_H
-
-#include "dcpomatic_time.h"
-#include <sub/subtitle.h>
-#include <boost/shared_ptr.hpp>
-#include <vector>
-
-class TextCaptionFileContent;
-class plain_text_time_test;
-class plain_text_coordinate_test;
-class plain_text_content_test;
-class plain_text_parse_test;
-
-/** @class TextCaptionFile
- *  @brief Base for TextCaptionFile decoder and examiner.
- *
- *  In fact this is sufficient for the examiner, so it's used as-is rather than deriving
- *  a pointless TextCaptionFileExaminer.
- */
-class TextCaptionFile
-{
-public:
-       explicit TextCaptionFile (boost::shared_ptr<const TextCaptionFileContent>);
-
-       boost::optional<ContentTime> first () const;
-       ContentTime length () const;
-
-protected:
-       std::vector<sub::Subtitle> _subtitles;
-};
-
-#endif
index a7cd0fd94ce93bf402b2ac152d4f9842c09f694e..7040bd530cf8b520f8e7b41d1dc97e364902279d 100644 (file)
@@ -40,8 +40,8 @@
 #include "decoder.h"
 #include "video_decoder.h"
 #include "audio_decoder.h"
-#include "text_content.h"
-#include "text_decoder.h"
+#include "caption_content.h"
+#include "caption_decoder.h"
 #include "ffmpeg_content.h"
 #include "audio_content.h"
 #include "dcp_decoder.h"
@@ -137,8 +137,8 @@ Player::setup_pieces ()
                        decoder->video->set_ignore (true);
                }
 
-               if (decoder->subtitle && _ignore_subtitle) {
-                       decoder->subtitle->set_ignore (true);
+               if (decoder->caption && _ignore_subtitle) {
+                       decoder->caption->set_ignore (true);
                }
 
                shared_ptr<DCPDecoder> dcp = dynamic_pointer_cast<DCPDecoder> (decoder);
@@ -165,10 +165,10 @@ Player::setup_pieces ()
                        decoder->audio->Data.connect (bind (&Player::audio, this, weak_ptr<Piece> (piece), _1, _2));
                }
 
-               if (decoder->subtitle) {
-                       decoder->subtitle->BitmapStart.connect (bind (&Player::bitmap_text_start, this, weak_ptr<Piece> (piece), _1));
-                       decoder->subtitle->PlainStart.connect (bind (&Player::plain_text_start, this, weak_ptr<Piece> (piece), _1));
-                       decoder->subtitle->Stop.connect (bind (&Player::subtitle_stop, this, weak_ptr<Piece> (piece), _1, _2));
+               if (decoder->caption) {
+                       decoder->caption->BitmapStart.connect (bind (&Player::bitmap_text_start, this, weak_ptr<Piece> (piece), _1));
+                       decoder->caption->PlainStart.connect (bind (&Player::plain_text_start, this, weak_ptr<Piece> (piece), _1));
+                       decoder->caption->Stop.connect (bind (&Player::subtitle_stop, this, weak_ptr<Piece> (piece), _1, _2));
                }
        }
 
@@ -209,9 +209,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 == TextContentProperty::COLOUR ||
-               property == TextContentProperty::EFFECT ||
-               property == TextContentProperty::EFFECT_COLOUR ||
+               property == CaptionContentProperty::COLOUR ||
+               property == CaptionContentProperty::EFFECT ||
+               property == CaptionContentProperty::EFFECT_COLOUR ||
                property == FFmpegContentProperty::SUBTITLE_STREAM ||
                property == FFmpegContentProperty::FILTERS
                ) {
@@ -220,17 +220,17 @@ Player::playlist_content_changed (weak_ptr<Content> w, int property, bool freque
                Changed (property, frequent);
 
        } else if (
-               property == TextContentProperty::LINE_SPACING ||
-               property == TextContentProperty::OUTLINE_WIDTH ||
-               property == TextContentProperty::Y_SCALE ||
-               property == TextContentProperty::FADE_IN ||
-               property == TextContentProperty::FADE_OUT ||
+               property == CaptionContentProperty::LINE_SPACING ||
+               property == CaptionContentProperty::OUTLINE_WIDTH ||
+               property == CaptionContentProperty::Y_SCALE ||
+               property == CaptionContentProperty::FADE_IN ||
+               property == CaptionContentProperty::FADE_OUT ||
                property == ContentProperty::VIDEO_FRAME_RATE ||
-               property == TextContentProperty::USE ||
-               property == TextContentProperty::X_OFFSET ||
-               property == TextContentProperty::Y_OFFSET ||
-               property == TextContentProperty::X_SCALE ||
-               property == TextContentProperty::FONTS ||
+               property == CaptionContentProperty::USE ||
+               property == CaptionContentProperty::X_OFFSET ||
+               property == CaptionContentProperty::Y_OFFSET ||
+               property == CaptionContentProperty::X_SCALE ||
+               property == CaptionContentProperty::FONTS ||
                property == VideoContentProperty::CROP ||
                property == VideoContentProperty::SCALE ||
                property == VideoContentProperty::FADE_IN ||
@@ -289,11 +289,11 @@ Player::film_changed (Film::Property p)
 }
 
 list<PositionImage>
-Player::transform_bitmap_texts (list<BitmapText> subs) const
+Player::transform_bitmap_captions (list<BitmapCaption> subs) const
 {
        list<PositionImage> all;
 
-       for (list<BitmapText>::const_iterator i = subs.begin(); i != subs.end(); ++i) {
+       for (list<BitmapCaption>::const_iterator i = subs.begin(); i != subs.end(); ++i) {
                if (!i->image) {
                        continue;
                }
@@ -406,11 +406,11 @@ Player::get_subtitle_fonts ()
 
        list<shared_ptr<Font> > fonts;
        BOOST_FOREACH (shared_ptr<Piece>& p, _pieces) {
-               if (p->content->subtitle) {
+               if (p->content->caption) {
                        /* XXX: things may go wrong if there are duplicate font IDs
                           with different font files.
                        */
-                       list<shared_ptr<Font> > f = p->content->subtitle->fonts ();
+                       list<shared_ptr<Font> > f = p->content->caption->fonts ();
                        copy (f.begin(), f.end(), back_inserter (fonts));
                }
        }
@@ -553,7 +553,7 @@ Player::pass ()
                        /* Given two choices at the same time, pick the one with a subtitle so we see it before
                           the video.
                        */
-                       if (!earliest_time || t < *earliest_time || (t == *earliest_time && i->decoder->subtitle)) {
+                       if (!earliest_time || t < *earliest_time || (t == *earliest_time && i->decoder->caption)) {
                                earliest_time = t;
                                earliest_content = i;
                        }
@@ -663,10 +663,10 @@ Player::subtitles_for_frame (DCPTime time) const
 
        int const vfr = _film->video_frame_rate();
 
-       BOOST_FOREACH (PlayerCaption i, _active_text[TEXT_SUBTITLE].get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_subtitles)) {
+       BOOST_FOREACH (PlayerCaption i, _active_captions[CAPTION_OPEN].get_burnt (DCPTimePeriod(time, time + DCPTime::from_frames(1, vfr)), _always_burn_subtitles)) {
 
                /* Image subtitles */
-               list<PositionImage> c = transform_bitmap_texts (i.image);
+               list<PositionImage> c = transform_bitmap_captions (i.image);
                copy (c.begin(), c.end(), back_inserter (subtitles));
 
                /* Text subtitles (rendered to an image) */
@@ -847,22 +847,22 @@ Player::bitmap_text_start (weak_ptr<Piece> wp, ContentBitmapCaption subtitle)
        }
 
        /* Apply content's subtitle offsets */
-       subtitle.sub.rectangle.x += piece->content->subtitle->x_offset ();
-       subtitle.sub.rectangle.y += piece->content->subtitle->y_offset ();
+       subtitle.sub.rectangle.x += piece->content->caption->x_offset ();
+       subtitle.sub.rectangle.y += piece->content->caption->y_offset ();
 
        /* Apply a corrective translation to keep the subtitle centred after the scale that is coming up */
-       subtitle.sub.rectangle.x -= subtitle.sub.rectangle.width * ((piece->content->subtitle->x_scale() - 1) / 2);
-       subtitle.sub.rectangle.y -= subtitle.sub.rectangle.height * ((piece->content->subtitle->y_scale() - 1) / 2);
+       subtitle.sub.rectangle.x -= subtitle.sub.rectangle.width * ((piece->content->caption->x_scale() - 1) / 2);
+       subtitle.sub.rectangle.y -= subtitle.sub.rectangle.height * ((piece->content->caption->y_scale() - 1) / 2);
 
        /* Apply content's subtitle scale */
-       subtitle.sub.rectangle.width *= piece->content->subtitle->x_scale ();
-       subtitle.sub.rectangle.height *= piece->content->subtitle->y_scale ();
+       subtitle.sub.rectangle.width *= piece->content->caption->x_scale ();
+       subtitle.sub.rectangle.height *= piece->content->caption->y_scale ();
 
        PlayerCaption ps;
        ps.image.push_back (subtitle.sub);
        DCPTime from (content_time_to_dcp (piece, subtitle.from()));
 
-       _active_text[subtitle.type()].add_from (wp, ps, from);
+       _active_captions[subtitle.type()].add_from (wp, ps, from);
 }
 
 void
@@ -881,10 +881,10 @@ Player::plain_text_start (weak_ptr<Piece> wp, ContentTextCaption subtitle)
        }
 
        BOOST_FOREACH (dcp::SubtitleString s, subtitle.subs) {
-               s.set_h_position (s.h_position() + piece->content->subtitle->x_offset ());
-               s.set_v_position (s.v_position() + piece->content->subtitle->y_offset ());
-               float const xs = piece->content->subtitle->x_scale();
-               float const ys = piece->content->subtitle->y_scale();
+               s.set_h_position (s.h_position() + piece->content->caption->x_offset ());
+               s.set_v_position (s.v_position() + piece->content->caption->y_offset ());
+               float const xs = piece->content->caption->x_scale();
+               float const ys = piece->content->caption->y_scale();
                float size = s.size();
 
                /* Adjust size to express the common part of the scaling;
@@ -901,17 +901,17 @@ Player::plain_text_start (weak_ptr<Piece> wp, ContentTextCaption subtitle)
                }
 
                s.set_in (dcp::Time(from.seconds(), 1000));
-               ps.text.push_back (TextCaption (s, piece->content->subtitle->outline_width()));
-               ps.add_fonts (piece->content->subtitle->fonts ());
+               ps.text.push_back (TextCaption (s, piece->content->caption->outline_width()));
+               ps.add_fonts (piece->content->caption->fonts ());
        }
 
-       _active_text[subtitle.type()].add_from (wp, ps, from);
+       _active_captions[subtitle.type()].add_from (wp, ps, from);
 }
 
 void
-Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to, TextType type)
+Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to, CaptionType type)
 {
-       if (!_active_text[type].have (wp)) {
+       if (!_active_captions[type].have (wp)) {
                return;
        }
 
@@ -926,10 +926,10 @@ Player::subtitle_stop (weak_ptr<Piece> wp, ContentTime to, TextType type)
                return;
        }
 
-       pair<PlayerCaption, DCPTime> from = _active_text[type].add_to (wp, dcp_to);
+       pair<PlayerCaption, DCPTime> from = _active_captions[type].add_to (wp, dcp_to);
 
-       if (piece->content->subtitle->use() && !_always_burn_subtitles && !piece->content->subtitle->burn()) {
-               Text (from.first, type, DCPTimePeriod (from.second, dcp_to));
+       if (piece->content->caption->use() && !_always_burn_subtitles && !piece->content->caption->burn()) {
+               Caption (from.first, type, DCPTimePeriod (from.second, dcp_to));
        }
 }
 
@@ -951,8 +951,8 @@ Player::seek (DCPTime time, bool accurate)
        }
 
        _audio_merger.clear ();
-       for (int i = 0; i < TEXT_COUNT; ++i) {
-               _active_text[i].clear ();
+       for (int i = 0; i < CAPTION_COUNT; ++i) {
+               _active_captions[i].clear ();
        }
 
        BOOST_FOREACH (shared_ptr<Piece> i, _pieces) {
@@ -1012,8 +1012,8 @@ void
 Player::do_emit_video (shared_ptr<PlayerVideo> pv, DCPTime time)
 {
        if (pv->eyes() == EYES_BOTH || pv->eyes() == EYES_RIGHT) {
-               for (int i = 0; i < TEXT_COUNT; ++i) {
-                       _active_text[i].clear_before (time);
+               for (int i = 0; i < CAPTION_COUNT; ++i) {
+                       _active_captions[i].clear_before (time);
                }
        }
 
index 16e9d57a5b38d92af5a0431b988a3c5413275d9a..5b6a0b7b4c5ed1276b56725f41c6256b74411f0c 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "player_caption.h"
 #include "active_captions.h"
-#include "content_text.h"
+#include "content_caption.h"
 #include "film.h"
 #include "content.h"
 #include "position_image.h"
@@ -101,7 +101,7 @@ public:
        /** Emitted when a caption is ready.  This signal may be emitted considerably
         *  after the corresponding Video.
         */
-       boost::signals2::signal<void (PlayerCaption, TextType, DCPTimePeriod)> Text;
+       boost::signals2::signal<void (PlayerCaption, CaptionType, DCPTimePeriod)> Caption;
 
 private:
        friend class PlayerWrapper;
@@ -116,7 +116,7 @@ private:
        void film_changed (Film::Property);
        void playlist_changed ();
        void playlist_content_changed (boost::weak_ptr<Content>, int, bool);
-       std::list<PositionImage> transform_bitmap_texts (std::list<BitmapText>) const;
+       std::list<PositionImage> transform_bitmap_captions (std::list<BitmapCaption>) const;
        Frame dcp_to_content_video (boost::shared_ptr<const Piece> piece, DCPTime t) const;
        DCPTime content_video_to_dcp (boost::shared_ptr<const Piece> piece, Frame f) const;
        Frame dcp_to_resampled_audio (boost::shared_ptr<const Piece> piece, DCPTime t) const;
@@ -128,7 +128,7 @@ private:
        void audio (boost::weak_ptr<Piece>, AudioStreamPtr, ContentAudio);
        void bitmap_text_start (boost::weak_ptr<Piece>, ContentBitmapCaption);
        void plain_text_start (boost::weak_ptr<Piece>, ContentTextCaption);
-       void subtitle_stop (boost::weak_ptr<Piece>, ContentTime, TextType);
+       void subtitle_stop (boost::weak_ptr<Piece>, ContentTime, CaptionType);
        DCPTime one_video_frame () const;
        void fill_audio (DCPTimePeriod period);
        std::pair<boost::shared_ptr<AudioBuffers>, DCPTime> discard_audio (
@@ -196,7 +196,7 @@ private:
        Empty _black;
        Empty _silent;
 
-       ActiveCaptions _active_text[TEXT_COUNT];
+       ActiveCaptions _active_captions[CAPTION_COUNT];
        boost::shared_ptr<AudioProcessor> _audio_processor;
 
        boost::signals2::scoped_connection _film_changed_connection;
index 2875790df92a9c4dc2aeac068707ebb0abf514f1..2f7e909aaa52aa03407ba1517b6e731bd3810ebb 100644 (file)
 
 */
 
-#ifndef DCPOMATIC_PLAYER_TEXT_H
-#define DCPOMATIC_PLAYER_TEXT_H
+#ifndef DCPOMATIC_PLAYER_CAPTION_H
+#define DCPOMATIC_PLAYER_CAPTION_H
 
-#include "bitmap_text.h"
+#include "bitmap_caption.h"
 #include "dcpomatic_time.h"
 #include "text_caption.h"
 
@@ -34,8 +34,8 @@ public:
        void add_fonts (std::list<boost::shared_ptr<Font> > fonts_);
        std::list<boost::shared_ptr<Font> > fonts;
 
-       /** BitmapTexts, with their rectangles transformed as specified by their content */
-       std::list<BitmapText> image;
+       /** BitmapCaptions, with their rectangles transformed as specified by their content */
+       std::list<BitmapCaption> image;
        std::list<TextCaption> text;
 };
 
index 13b4d7337212a6a34be6d3fd89ad39e8d832935e..a5451bafa418e21fedacb48eb319f8dfb8d33bcc 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -20,7 +20,7 @@
 
 #include "playlist.h"
 #include "video_content.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include "ffmpeg_decoder.h"
 #include "ffmpeg_content.h"
 #include "image_decoder.h"
@@ -135,7 +135,7 @@ Playlist::maybe_sequence ()
 
        DCPTime next;
        BOOST_FOREACH (shared_ptr<Content> i, _content) {
-               if (!i->subtitle || find (placed.begin(), placed.end(), i) != placed.end()) {
+               if (!i->caption || find (placed.begin(), placed.end(), i) != placed.end()) {
                        continue;
                }
 
@@ -155,7 +155,7 @@ Playlist::video_identifier () const
        string t;
 
        BOOST_FOREACH (shared_ptr<const Content> i, _content) {
-               if (i->video || (i->subtitle && i->subtitle->burn())) {
+               if (i->video || (i->caption && i->caption->burn())) {
                        t += i->identifier ();
                }
        }
@@ -366,7 +366,7 @@ Playlist::subtitle_end () const
 {
        DCPTime end;
        BOOST_FOREACH (shared_ptr<Content> i, _content) {
-               if (i->subtitle) {
+               if (i->caption) {
                        end = max (end, i->end ());
                }
        }
index 77d5833533373334d91507bf5db5e112442ca85d..8fb15c133c100684e3eb2c70c1041c838e346956 100644 (file)
@@ -528,7 +528,7 @@ ReelWriter::write (shared_ptr<const AudioBuffers> audio)
 }
 
 void
-ReelWriter::write (PlayerCaption subs, TextType type, DCPTimePeriod period)
+ReelWriter::write (PlayerCaption subs, CaptionType type, DCPTimePeriod period)
 {
        /* XXX: we need separate libdcp asset types here and to know how different they are */
 
@@ -565,7 +565,7 @@ ReelWriter::write (PlayerCaption subs, TextType type, DCPTimePeriod period)
                _subtitle_asset->add (shared_ptr<dcp::Subtitle>(new dcp::SubtitleString(i)));
        }
 
-       BOOST_FOREACH (BitmapText i, subs.image) {
+       BOOST_FOREACH (BitmapCaption i, subs.image) {
                _subtitle_asset->add (
                        shared_ptr<dcp::Subtitle>(
                                new dcp::SubtitleImage(
index cd22fa775ca969c414da1996743e806b358107d9..06f19f15a7a7e9eef3742269fbcec5309b3f7897 100644 (file)
@@ -60,7 +60,7 @@ public:
        void fake_write (Frame frame, Eyes eyes, int size);
        void repeat_write (Frame frame, Eyes eyes);
        void write (boost::shared_ptr<const AudioBuffers> audio);
-       void write (PlayerCaption text, TextType type, DCPTimePeriod period);
+       void write (PlayerCaption text, CaptionType type, DCPTimePeriod period);
 
        void finish ();
        boost::shared_ptr<dcp::Reel> create_reel (std::list<ReferencedReelAsset> const & refs, std::list<boost::shared_ptr<Font> > const & fonts);
diff --git a/src/lib/text_caption_file.cc b/src/lib/text_caption_file.cc
new file mode 100644 (file)
index 0000000..11d4517
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+    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 "text_caption_file.h"
+#include "cross.h"
+#include "exceptions.h"
+#include "text_caption_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 boost::optional;
+using dcp::Data;
+
+TextCaptionFile::TextCaptionFile (shared_ptr<const TextCaptionFileContent> 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);
+
+       /* Fix OS X line endings */
+       size_t utf8_len = strlen (utf8.get ());
+       for (size_t i = 0; i < utf8_len; ++i) {
+               if (utf8[i] == '\r' && ((i == utf8_len - 1) || utf8[i + 1] != '\n')) {
+                       utf8[i] = '\n';
+               }
+       }
+
+       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;
+}
+
+/** @return time of first subtitle, if there is one */
+optional<ContentTime>
+TextCaptionFile::first () const
+{
+       if (_subtitles.empty()) {
+               return optional<ContentTime>();
+       }
+
+       return ContentTime::from_seconds(_subtitles[0].from.all_as_seconds());
+}
+
+ContentTime
+TextCaptionFile::length () const
+{
+       if (_subtitles.empty ()) {
+               return ContentTime ();
+       }
+
+       return ContentTime::from_seconds (_subtitles.back().to.all_as_seconds ());
+}
diff --git a/src/lib/text_caption_file.h b/src/lib/text_caption_file.h
new file mode 100644 (file)
index 0000000..4a5657a
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+    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/>.
+
+*/
+
+#ifndef DCPOMATIC_TEXT_CAPTION_FILE_H
+#define DCPOMATIC_TEXT_CAPTION_FILE_H
+
+#include "dcpomatic_time.h"
+#include <sub/subtitle.h>
+#include <boost/shared_ptr.hpp>
+#include <vector>
+
+class TextCaptionFileContent;
+class plain_text_time_test;
+class plain_text_coordinate_test;
+class plain_text_content_test;
+class plain_text_parse_test;
+
+/** @class TextCaptionFile
+ *  @brief Base for TextCaptionFile decoder and examiner.
+ *
+ *  In fact this is sufficient for the examiner, so it's used as-is rather than deriving
+ *  a pointless TextCaptionFileExaminer.
+ */
+class TextCaptionFile
+{
+public:
+       explicit TextCaptionFile (boost::shared_ptr<const TextCaptionFileContent>);
+
+       boost::optional<ContentTime> first () const;
+       ContentTime length () const;
+
+protected:
+       std::vector<sub::Subtitle> _subtitles;
+};
+
+#endif
index df5de93ef5f647c82e52b4f7f5fd92ab686316aa..cb7d1511ba001a7f75a1b2e7b4ea1552910cd296 100644 (file)
 
 #include "text_caption_file_content.h"
 #include "util.h"
-#include "plain_text_file.h"
+#include "text_caption_file.h"
 #include "film.h"
 #include "font.h"
-#include "text_content.h"
+#include "caption_content.h"
 #include <dcp/raw_convert.h>
 #include <libxml++/libxml++.h>
 #include <iostream>
@@ -38,14 +38,14 @@ using dcp::raw_convert;
 TextCaptionFileContent::TextCaptionFileContent (shared_ptr<const Film> film, boost::filesystem::path path)
        : Content (film, path)
 {
-       subtitle.reset (new TextContent (this));
+       caption.reset (new CaptionContent (this));
 }
 
 TextCaptionFileContent::TextCaptionFileContent (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);
+       caption = CaptionContent::from_xml (this, node, version);
 }
 
 void
@@ -55,11 +55,11 @@ TextCaptionFileContent::examine (boost::shared_ptr<Job> job)
        TextCaptionFile s (shared_from_this ());
 
        /* Default to turning these subtitles on */
-       subtitle->set_use (true);
+       caption->set_use (true);
 
        boost::mutex::scoped_lock lm (_mutex);
        _length = s.length ();
-       subtitle->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
+       caption->add_font (shared_ptr<Font> (new Font (TEXT_FONT_ID)));
 }
 
 string
@@ -80,8 +80,8 @@ TextCaptionFileContent::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);
+       if (caption) {
+               caption->as_xml (node);
        }
 
        node->add_child("Length")->add_child_text (raw_convert<string> (_length.get ()));
index d1a72faebd4efb1ca8bcc059df449d7aadbd2924..46217e49b550b2a4421afab0febc21449081e945 100644 (file)
@@ -20,8 +20,8 @@
 
 #include "text_caption_file_decoder.h"
 #include "text_caption_file_content.h"
-#include "text_content.h"
-#include "text_decoder.h"
+#include "caption_content.h"
+#include "caption_decoder.h"
 #include <dcp/subtitle_string.h>
 #include <boost/foreach.hpp>
 #include <iostream>
@@ -43,7 +43,7 @@ TextCaptionFileDecoder::TextCaptionFileDecoder (shared_ptr<const TextCaptionFile
        if (!_subtitles.empty()) {
                first = content_time_period(_subtitles[0]).from;
        }
-       subtitle.reset (new TextDecoder (this, content->subtitle, log, first));
+       caption.reset (new CaptionDecoder (this, content->caption, log, first));
 }
 
 void
@@ -73,7 +73,7 @@ TextCaptionFileDecoder::pass ()
        }
 
        ContentTimePeriod const p = content_time_period (_subtitles[_next]);
-       subtitle->emit_plain (p, _subtitles[_next]);
+       caption->emit_plain (p, _subtitles[_next]);
 
        ++_next;
        return false;
index 7f889e72d1bd7822df2841f2333eb1cdd0985109..7697775717fafd12cd3fb989d1e914ca9a59a41e 100644 (file)
 
 */
 
-#ifndef DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
-#define DCPOMATIC_PLAIN_TEXT_FILE_DECODER_H
+#ifndef DCPOMATIC_TEXT_CAPTION_FILE_DECODER_H
+#define DCPOMATIC_TEXT_CAPTION_FILE_DECODER_H
 
-#include "plain_text_file.h"
+#include "text_caption_file.h"
 #include "decoder.h"
 
 class TextCaptionFileContent;
diff --git a/src/lib/text_content.cc b/src/lib/text_content.cc
deleted file mode 100644 (file)
index 8e1e416..0000000
+++ /dev/null
@@ -1,528 +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 "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;
-int const TextContentProperty::TYPE = 515;
-
-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)
-       , _type (TEXT_SUBTITLE)
-{
-
-}
-
-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))
-       , _type (TEXT_SUBTITLE)
-{
-       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 ();
-
-       _type = string_to_text_type (node->optional_string_child("TextType").get_value_or("subtitle"));
-}
-
-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"));
-       }
-
-       root->add_child("TextType")->add_child_text (text_type_to_string(_type));
-}
-
-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_type (TextType type)
-{
-       maybe_set (_type, type, TextContentProperty::TYPE);
-}
-
-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
deleted file mode 100644 (file)
index cca678a..0000000
+++ /dev/null
@@ -1,212 +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 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;
-       static int const TYPE;
-};
-
-/** @class TextContent
- *  @brief Description of how some text content should be presented.
- *
- *  There are `bitmap' subtitles and `plain' 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 ();
-       void set_type (TextType type);
-
-       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;
-       }
-
-       TextType type () const {
-               boost::mutex::scoped_lock lm (_mutex);
-               return _type;
-       }
-
-       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;
-       TextType _type;
-};
-
-#endif
diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc
deleted file mode 100644 (file)
index 932a575..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 "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_bitmap_start (ContentTime from, shared_ptr<Image> image, dcpomatic::Rect<double> rect)
-{
-       BitmapStart (ContentBitmapCaption (from, _content->type(), image, rect));
-       _position = from;
-}
-
-void
-TextDecoder::emit_plain_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));
-               }
-       }
-
-       PlainStart (ContentTextCaption (from, _content->type(), s));
-       _position = from;
-}
-
-void
-TextDecoder::emit_plain_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_plain_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_plain_start (from, out);
-}
-
-void
-TextDecoder::emit_stop (ContentTime to)
-{
-       Stop (to, _content->type());
-}
-
-void
-TextDecoder::emit_plain (ContentTimePeriod period, list<dcp::SubtitleString> s)
-{
-       emit_plain_start (period.from, s);
-       emit_stop (period.to);
-}
-
-void
-TextDecoder::emit_plain (ContentTimePeriod period, sub::Subtitle const & s)
-{
-       emit_plain_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
deleted file mode 100644 (file)
index ed27639..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_text.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_bitmap_start (ContentTime from, boost::shared_ptr<Image> image, dcpomatic::Rect<double> rect);
-       void emit_plain_start (ContentTime from, std::list<dcp::SubtitleString> s);
-       void emit_plain_start (ContentTime from, sub::Subtitle const & subtitle);
-       void emit_plain (ContentTimePeriod period, std::list<dcp::SubtitleString> s);
-       void emit_plain (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 (ContentBitmapCaption)> BitmapStart;
-       boost::signals2::signal<void (ContentTextCaption)> PlainStart;
-       boost::signals2::signal<void (ContentTime, TextType)> Stop;
-
-private:
-       boost::shared_ptr<const TextContent> _content;
-       ContentTime _position;
-};
-
-#endif
index 68e00c8d532c55a4fce389721991b9b56a43b6c6..97373b24ee52a481f803f35e44e28863b3f46258 100644 (file)
@@ -91,26 +91,26 @@ Crop::as_xml (xmlpp::Node* node) const
        node->add_child("BottomCrop")->add_child_text (raw_convert<string> (bottom));
 }
 
-TextType
-string_to_text_type (string s)
+CaptionType
+string_to_caption_type (string s)
 {
-       if (s == "subtitle") {
-               return TEXT_SUBTITLE;
-       } else if (s == "ccap") {
-               return TEXT_CLOSED_CAPTION;
+       if (s == "open") {
+               return CAPTION_OPEN;
+       } else if (s == "closed") {
+               return CAPTION_CLOSED;
        } else {
-               throw MetadataError (String::compose ("Unknown text type %1", s));
+               throw MetadataError (String::compose ("Unknown caption type %1", s));
        }
 }
 
 string
-text_type_to_string (TextType t)
+caption_type_to_string (CaptionType t)
 {
        switch (t) {
-       case TEXT_SUBTITLE:
-               return "subtitle";
-       case TEXT_CLOSED_CAPTION:
-               return "ccap";
+       case CAPTION_OPEN:
+               return "open";
+       case CAPTION_CLOSED:
+               return "closed";
        default:
                DCPOMATIC_ASSERT (false);
        }
index e52daca00f0751e7c84b7671e77ea01d2fa2e2d4..3337087ebfb71e630f30fd0d723629d857548fb8 100644 (file)
@@ -31,7 +31,7 @@
 class Content;
 class VideoContent;
 class AudioContent;
-class TextContent;
+class CaptionContent;
 class FFmpegContent;
 
 namespace cxml {
@@ -129,15 +129,15 @@ enum ReelType
        REELTYPE_BY_LENGTH
 };
 
-enum TextType
+enum CaptionType
 {
-       TEXT_SUBTITLE,
-       TEXT_CLOSED_CAPTION,
-       TEXT_COUNT
+       CAPTION_OPEN,
+       CAPTION_CLOSED,
+       CAPTION_COUNT
 };
 
-extern std::string text_type_to_string (TextType t);
-extern TextType string_to_text_type (std::string s);
+extern std::string caption_type_to_string (CaptionType t);
+extern CaptionType string_to_caption_type (std::string s);
 
 /** @struct Crop
  *  @brief A description of the crop of an image or video.
index ea4a6d29beab4616dde6f4ff423b7b29d47ce050..c0a774f03584a2c0e859fdb84aec802c450132cb 100644 (file)
@@ -95,8 +95,8 @@ Writer::Writer (shared_ptr<const Film> film, weak_ptr<Job> j)
           and captions arrive to the Writer in sequence.  This is not so for video.
        */
        _audio_reel = _reels.begin ();
-       for (int i = 0; i < TEXT_COUNT; ++i) {
-               _text_reel[i] = _reels.begin ();
+       for (int i = 0; i < CAPTION_COUNT; ++i) {
+               _caption_reel[i] = _reels.begin ();
        }
 
        /* Check that the signer is OK if we need one */
@@ -665,16 +665,16 @@ Writer::can_fake_write (Frame frame) const
 }
 
 void
-Writer::write (PlayerCaption text, TextType type, DCPTimePeriod period)
+Writer::write (PlayerCaption text, CaptionType type, DCPTimePeriod period)
 {
-       while (_text_reel[type]->period().to <= period.from) {
-               ++_text_reel[type];
-               DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
+       while (_caption_reel[type]->period().to <= period.from) {
+               ++_caption_reel[type];
+               DCPOMATIC_ASSERT (_caption_reel[type] != _reels.end());
        }
 
-       DCPOMATIC_ASSERT (_text_reel[type] != _reels.end());
+       DCPOMATIC_ASSERT (_caption_reel[type] != _reels.end());
 
-       _text_reel[type]->write (text, type, period);
+       _caption_reel[type]->write (text, type, period);
 }
 
 void
index a776e54c3c848d18f27bf46a15bd4ce5728e1114..f67419072a697dd6aed9d11d0dec5c85ef4a7179 100644 (file)
@@ -104,7 +104,7 @@ public:
        bool can_repeat (Frame) const;
        void repeat (Frame, Eyes);
        void write (boost::shared_ptr<const AudioBuffers>, DCPTime time);
-       void write (PlayerCaption text, TextType type, DCPTimePeriod period);
+       void write (PlayerCaption text, CaptionType type, DCPTimePeriod period);
        void write (std::list<boost::shared_ptr<Font> > fonts);
        void write (ReferencedReelAsset asset);
        void finish ();
@@ -124,7 +124,7 @@ private:
        boost::weak_ptr<Job> _job;
        std::vector<ReelWriter> _reels;
        std::vector<ReelWriter>::iterator _audio_reel;
-       std::vector<ReelWriter>::iterator _text_reel[TEXT_COUNT];
+       std::vector<ReelWriter>::iterator _caption_reel[CAPTION_COUNT];
 
        /** our thread, or 0 */
        boost::thread* _thread;
index 71c94c28b0632e6632ff11003991ad4bd53aa6bd..a841e5b552522d7c8425243f537fab561317b26c 100644 (file)
@@ -38,6 +38,8 @@ sources = """
           audio_ring_buffers.cc
           audio_stream.cc
           butler.cc
+          caption_content.cc
+          caption_decoder.cc
           case_insensitive_sorter.cc
           cinema.cc
           cinema_kdms.cc
@@ -55,8 +57,8 @@ sources = """
           dcp_encoder.cc
           dcp_examiner.cc
           dcp_subtitle.cc
-          dcp_text_content.cc
-          dcp_text_decoder.cc
+          dcp_subtitle_content.cc
+          dcp_subtitle_decoder.cc
           dcp_video.cc
           dcpomatic_socket.cc
           dcpomatic_time.cc
@@ -132,9 +134,7 @@ sources = """
           server.cc
           shuffler.cc
           string_log_entry.cc
-          text_content.cc
-          text_decoder.cc
-          plain_text_file.cc
+          text_caption_file.cc
           text_caption_file_content.cc
           text_caption_file_decoder.cc
           timer.cc
index 934e5750521900c0c1487e7824ea55b9ea0be03b..9262be1b5f71a5123df1311f62ab3ccacc5b0e73 100644 (file)
@@ -71,7 +71,7 @@
 #include "lib/transcode_job.h"
 #include "lib/dkdm_wrapper.h"
 #include "lib/audio_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include <dcp/exceptions.h>
 #include <dcp/raw_convert.h>
 #include <wx/generic/aboutdlgg.h>
@@ -563,7 +563,7 @@ private:
        {
                DCPOMATIC_ASSERT (_clipboard);
 
-               PasteDialog* d = new PasteDialog (this, static_cast<bool>(_clipboard->video), static_cast<bool>(_clipboard->audio), static_cast<bool>(_clipboard->subtitle));
+               PasteDialog* d = new PasteDialog (this, static_cast<bool>(_clipboard->video), static_cast<bool>(_clipboard->audio), static_cast<bool>(_clipboard->caption));
                if (d->ShowModal() == wxID_OK) {
                        BOOST_FOREACH (shared_ptr<Content> i, _film_editor->content_panel()->selected()) {
                                if (d->video() && i->video) {
@@ -574,9 +574,9 @@ private:
                                        DCPOMATIC_ASSERT (_clipboard->audio);
                                        i->audio->take_settings_from (_clipboard->audio);
                                }
-                               if (d->subtitle() && i->subtitle) {
-                                       DCPOMATIC_ASSERT (_clipboard->subtitle);
-                                       i->subtitle->take_settings_from (_clipboard->subtitle);
+                               if (d->caption() && i->caption) {
+                                       DCPOMATIC_ASSERT (_clipboard->caption);
+                                       i->caption->take_settings_from (_clipboard->caption);
                                }
                        }
                }
index 3f56f47529fd59b41397f73b0d023ecda58e22cb..0af44fd05d2dd27a89800c13c057a43f6d48d1cd 100644 (file)
@@ -27,7 +27,7 @@
 #include "lib/job_manager.h"
 #include "lib/job.h"
 #include "lib/video_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/ratio.h"
 #include "lib/verify_dcp_job.h"
 #include "lib/dcp_examiner.h"
@@ -618,8 +618,8 @@ private:
 
        void setup_from_dcp (shared_ptr<DCPContent> dcp)
        {
-               if (dcp->subtitle) {
-                       dcp->subtitle->set_use (true);
+               if (dcp->caption) {
+                       dcp->caption->set_use (true);
                }
 
                if (dcp->video) {
index 20a0ad143c3a2e402eeab9a712039a11f42fdc15..c70a9ad8c843368e483a4c179f57fe7ba2b7ab3a 100644 (file)
 #include "lib/ffmpeg_content.h"
 #include "lib/text_caption_file_content.h"
 #include "lib/ffmpeg_subtitle_stream.h"
-#include "lib/dcp_text_content.h"
+#include "lib/dcp_subtitle_content.h"
 #include "lib/text_caption_file_decoder.h"
-#include "lib/dcp_text_decoder.h"
+#include "lib/dcp_subtitle_decoder.h"
 #include "lib/dcp_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/decoder_factory.h"
 #include <wx/spinctrl.h>
 #include <boost/foreach.hpp>
@@ -216,16 +216,16 @@ CaptionPanel::film_content_changed (int property)
                        }
                }
                setup_sensitivity ();
-       } else if (property == TextContentProperty::USE) {
-               checked_set (_use, scs ? scs->subtitle->use() : false);
+       } else if (property == CaptionContentProperty::USE) {
+               checked_set (_use, scs ? scs->caption->use() : false);
                setup_sensitivity ();
-       } else if (property == TextContentProperty::TYPE) {
+       } else if (property == CaptionContentProperty::TYPE) {
                if (scs) {
-                       switch (scs->subtitle->type()) {
-                       case TEXT_SUBTITLE:
+                       switch (scs->caption->type()) {
+                       case CAPTION_OPEN:
                                _type->SetSelection (0);
                                break;
-                       case TEXT_CLOSED_CAPTION:
+                       case CAPTION_CLOSED:
                                _type->SetSelection (1);
                                break;
                        default:
@@ -235,20 +235,20 @@ CaptionPanel::film_content_changed (int property)
                        _type->SetSelection (0);
                }
                setup_sensitivity ();
-       } else if (property == TextContentProperty::BURN) {
-               checked_set (_burn, scs ? scs->subtitle->burn() : false);
-       } else if (property == TextContentProperty::X_OFFSET) {
-               checked_set (_x_offset, scs ? lrint (scs->subtitle->x_offset() * 100) : 0);
-       } else if (property == TextContentProperty::Y_OFFSET) {
-               checked_set (_y_offset, scs ? lrint (scs->subtitle->y_offset() * 100) : 0);
-       } else if (property == TextContentProperty::X_SCALE) {
-               checked_set (_x_scale, scs ? lrint (scs->subtitle->x_scale() * 100) : 100);
-       } else if (property == TextContentProperty::Y_SCALE) {
-               checked_set (_y_scale, scs ? lrint (scs->subtitle->y_scale() * 100) : 100);
-       } else if (property == TextContentProperty::LINE_SPACING) {
-               checked_set (_line_spacing, scs ? lrint (scs->subtitle->line_spacing() * 100) : 100);
-       } else if (property == TextContentProperty::LANGUAGE) {
-               checked_set (_language, scs ? scs->subtitle->language() : "");
+       } else if (property == CaptionContentProperty::BURN) {
+               checked_set (_burn, scs ? scs->caption->burn() : false);
+       } else if (property == CaptionContentProperty::X_OFFSET) {
+               checked_set (_x_offset, scs ? lrint (scs->caption->x_offset() * 100) : 0);
+       } else if (property == CaptionContentProperty::Y_OFFSET) {
+               checked_set (_y_offset, scs ? lrint (scs->caption->y_offset() * 100) : 0);
+       } else if (property == CaptionContentProperty::X_SCALE) {
+               checked_set (_x_scale, scs ? lrint (scs->caption->x_scale() * 100) : 100);
+       } else if (property == CaptionContentProperty::Y_SCALE) {
+               checked_set (_y_scale, scs ? lrint (scs->caption->y_scale() * 100) : 100);
+       } else if (property == CaptionContentProperty::LINE_SPACING) {
+               checked_set (_line_spacing, scs ? lrint (scs->caption->line_spacing() * 100) : 100);
+       } else if (property == CaptionContentProperty::LANGUAGE) {
+               checked_set (_language, scs ? scs->caption->language() : "");
        } else if (property == DCPContentProperty::REFERENCE_SUBTITLE) {
                if (scs) {
                        shared_ptr<DCPContent> dcp = dynamic_pointer_cast<DCPContent> (scs);
@@ -267,7 +267,7 @@ void
 CaptionPanel::use_toggled ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_use (_use->GetValue());
+               i->caption->set_use (_use->GetValue());
        }
 }
 
@@ -277,10 +277,10 @@ CaptionPanel::type_changed ()
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle()) {
                switch (_type->GetSelection()) {
                case 0:
-                       i->subtitle->set_type (TEXT_SUBTITLE);
+                       i->caption->set_type (CAPTION_OPEN);
                        break;
                case 1:
-                       i->subtitle->set_type (TEXT_CLOSED_CAPTION);
+                       i->caption->set_type (CAPTION_CLOSED);
                        break;
                }
        }
@@ -290,7 +290,7 @@ void
 CaptionPanel::burn_toggled ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_burn (_burn->GetValue());
+               i->caption->set_burn (_burn->GetValue());
        }
 }
 
@@ -305,9 +305,9 @@ CaptionPanel::setup_sensitivity ()
                shared_ptr<const FFmpegContent> fc = boost::dynamic_pointer_cast<const FFmpegContent> (i);
                shared_ptr<const TextCaptionFileContent> sc = boost::dynamic_pointer_cast<const TextCaptionFileContent> (i);
                shared_ptr<const DCPContent> dc = boost::dynamic_pointer_cast<const DCPContent> (i);
-               shared_ptr<const DCPTextContent> dsc = boost::dynamic_pointer_cast<const DCPTextContent> (i);
+               shared_ptr<const DCPSubtitleContent> dsc = boost::dynamic_pointer_cast<const DCPSubtitleContent> (i);
                if (fc) {
-                       if (fc->subtitle) {
+                       if (fc->caption) {
                                ++ffmpeg_subs;
                                ++any_subs;
                        }
@@ -373,7 +373,7 @@ void
 CaptionPanel::x_offset_changed ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_x_offset (_x_offset->GetValue() / 100.0);
+               i->caption->set_x_offset (_x_offset->GetValue() / 100.0);
        }
 }
 
@@ -381,7 +381,7 @@ void
 CaptionPanel::y_offset_changed ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_y_offset (_y_offset->GetValue() / 100.0);
+               i->caption->set_y_offset (_y_offset->GetValue() / 100.0);
        }
 }
 
@@ -390,7 +390,7 @@ CaptionPanel::x_scale_changed ()
 {
        ContentList c = _parent->selected_subtitle ();
        if (c.size() == 1) {
-               c.front()->subtitle->set_x_scale (_x_scale->GetValue() / 100.0);
+               c.front()->caption->set_x_scale (_x_scale->GetValue() / 100.0);
        }
 }
 
@@ -398,7 +398,7 @@ void
 CaptionPanel::y_scale_changed ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_y_scale (_y_scale->GetValue() / 100.0);
+               i->caption->set_y_scale (_y_scale->GetValue() / 100.0);
        }
 }
 
@@ -406,7 +406,7 @@ void
 CaptionPanel::line_spacing_changed ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_line_spacing (_line_spacing->GetValue() / 100.0);
+               i->caption->set_line_spacing (_line_spacing->GetValue() / 100.0);
        }
 }
 
@@ -414,7 +414,7 @@ void
 CaptionPanel::language_changed ()
 {
        BOOST_FOREACH (shared_ptr<Content> i, _parent->selected_subtitle ()) {
-               i->subtitle->set_language (wx_to_std (_language->GetValue()));
+               i->caption->set_language (wx_to_std (_language->GetValue()));
        }
 }
 
@@ -422,16 +422,16 @@ void
 CaptionPanel::content_selection_changed ()
 {
        film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS);
-       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 (TextContentProperty::TYPE);
+       film_content_changed (CaptionContentProperty::USE);
+       film_content_changed (CaptionContentProperty::BURN);
+       film_content_changed (CaptionContentProperty::X_OFFSET);
+       film_content_changed (CaptionContentProperty::Y_OFFSET);
+       film_content_changed (CaptionContentProperty::X_SCALE);
+       film_content_changed (CaptionContentProperty::Y_SCALE);
+       film_content_changed (CaptionContentProperty::LINE_SPACING);
+       film_content_changed (CaptionContentProperty::LANGUAGE);
+       film_content_changed (CaptionContentProperty::FONTS);
+       film_content_changed (CaptionContentProperty::TYPE);
        film_content_changed (DCPContentProperty::REFERENCE_SUBTITLE);
 }
 
index 3dc0e2b63e50e9788b0a44956e5d592c4cb69271..9d6d9a00643467fc3fcbece5e1a9d350e8d62918 100644 (file)
@@ -28,7 +28,7 @@
 #include "image_sequence_dialog.h"
 #include "film_viewer.h"
 #include "lib/audio_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/video_content.h"
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
@@ -40,7 +40,7 @@
 #include "lib/log.h"
 #include "lib/compose.hpp"
 #include "lib/text_caption_file_content.h"
-#include "lib/plain_text_file.h"
+#include "lib/text_caption_file.h"
 #include <wx/wx.h>
 #include <wx/notebook.h>
 #include <wx/listctrl.h>
@@ -196,7 +196,7 @@ ContentPanel::selected_subtitle ()
        ContentList sc;
 
        BOOST_FOREACH (shared_ptr<Content> i, selected ()) {
-               if (i->subtitle) {
+               if (i->caption) {
                        sc.push_back (i);
                }
        }
@@ -447,7 +447,7 @@ ContentPanel::setup_sensitivity ()
 
        _video_panel->Enable    (_generally_sensitive && video_selection.size() > 0);
        _audio_panel->Enable    (_generally_sensitive && audio_selection.size() > 0);
-       _caption_panel->Enable  (_generally_sensitive && selection.size() == 1 && selection.front()->subtitle);
+       _caption_panel->Enable  (_generally_sensitive && selection.size() == 1 && selection.front()->caption);
        _timing_panel->Enable   (_generally_sensitive);
 }
 
index 5a380ec4e71ce567a60a7076a7f330c1a6c744e1..fcec93a31f09c91898ea8dd225c955fb0d266179 100644 (file)
@@ -32,7 +32,7 @@
 #include "lib/ffmpeg_content.h"
 #include "lib/audio_processor.h"
 #include "lib/video_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.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 ||
-           property == TextContentProperty::USE ||
-           property == TextContentProperty::BURN ||
+           property == CaptionContentProperty::USE ||
+           property == CaptionContentProperty::BURN ||
            property == VideoContentProperty::SCALE ||
            property == DCPContentProperty::REFERENCE_VIDEO ||
            property == DCPContentProperty::REFERENCE_AUDIO ||
index c295ec327f79b9b81060c02fcb9328d455f0d54d..528b3999bd036c529e90ba1bbffe7b19394fde3b 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -24,7 +24,7 @@
 #include "font_files_dialog.h"
 #include "lib/font.h"
 #include "lib/content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include <wx/wx.h>
 #include <boost/foreach.hpp>
 #include <iostream>
@@ -105,7 +105,7 @@ FontsDialog::setup ()
 
        _fonts->DeleteAllItems ();
        size_t n = 0;
-       BOOST_FOREACH (shared_ptr<Font> i, content->subtitle->fonts ()) {
+       BOOST_FOREACH (shared_ptr<Font> i, content->caption->fonts ()) {
                wxListItem item;
                item.SetId (n);
                _fonts->InsertItem (item);
@@ -145,7 +145,7 @@ FontsDialog::edit_clicked ()
        int const item = _fonts->GetNextItem (-1, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED);
        string const id = wx_to_std (_fonts->GetItemText (item, 0));
        shared_ptr<Font> font;
-       BOOST_FOREACH (shared_ptr<Font> i, content->subtitle->fonts()) {
+       BOOST_FOREACH (shared_ptr<Font> i, content->caption->fonts()) {
                if (i->id() == id) {
                        font = i;
                }
index eade31490540177e2f6486a15913bc902aceee7e..07a3b156c240bc94e88d471518e5cb07721a74d5 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "paste_dialog.h"
 
-PasteDialog::PasteDialog (wxWindow* parent, bool video, bool audio, bool subtitle)
+PasteDialog::PasteDialog (wxWindow* parent, bool video, bool audio, bool caption)
        : TableDialog (parent, _("Paste"), 1, 0, true)
 {
        _video = new wxCheckBox (this, wxID_ANY, _("Paste video settings"));
@@ -29,9 +29,9 @@ PasteDialog::PasteDialog (wxWindow* parent, bool video, bool audio, bool subtitl
        _audio = new wxCheckBox (this, wxID_ANY, _("Paste audio settings"));
        _audio->Enable (audio);
        add (_audio);
-       _subtitle = new wxCheckBox (this, wxID_ANY, _("Paste subtitle settings"));
-       _subtitle->Enable (subtitle);
-       add (_subtitle);
+       _caption = new wxCheckBox (this, wxID_ANY, _("Paste caption settings"));
+       _caption->Enable (caption);
+       add (_caption);
 
        layout ();
 }
@@ -49,7 +49,7 @@ PasteDialog::audio () const
 }
 
 bool
-PasteDialog::subtitle () const
+PasteDialog::caption () const
 {
-       return _subtitle->GetValue ();
+       return _caption->GetValue ();
 }
index 204f421d80d4dbad700e9fec3c32a4a846f1cdfe..7de38fd2caaf1a378018119416e4230d3dfaa757 100644 (file)
 class PasteDialog : public TableDialog
 {
 public:
-       PasteDialog (wxWindow* parent, bool video, bool audio, bool subtitle);
+       PasteDialog (wxWindow* parent, bool video, bool audio, bool caption);
 
        bool video () const;
        bool audio () const;
-       bool subtitle () const;
+       bool caption () const;
 
 private:
        wxCheckBox* _video;
        wxCheckBox* _audio;
-       wxCheckBox* _subtitle;
+       wxCheckBox* _caption;
 };
index 9c5684e74015ab534f65fe8014fe55f40abb81c8..aab8c2cd576d2d45aea01fe3b55a6e9fb58d5bd4 100644 (file)
@@ -131,7 +131,7 @@ PlayerInformation::triggered_update ()
        if (dcp->audio && !dcp->audio->streams().empty()) {
                checked_set (_dcp[r++], wxString::Format(_("Audio channels: %d"), dcp->audio->streams().front()->channels()));
        }
-       if (dcp->subtitle) {
+       if (dcp->caption) {
                checked_set (_dcp[r++], _("Subtitles: yes"));
        } else {
                checked_set (_dcp[r++], _("Subtitles: no"));
index de6f1c8e8eed508a4514a7e35f4f3f97d8866f54..c0a6a0df6fce3241c8b84a51cfa404c6cf888330 100644 (file)
@@ -21,7 +21,7 @@
 #include "subtitle_appearance_dialog.h"
 #include "rgba_colour_picker.h"
 #include "lib/text_caption_file_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/ffmpeg_subtitle_stream.h"
 #include "lib/ffmpeg_content.h"
 #include <wx/wx.h>
@@ -126,7 +126,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
        _effect->Append (_("Outline"));
        _effect->Append (_("Shadow"));;
 
-       optional<dcp::Colour> colour = _content->subtitle->colour();
+       optional<dcp::Colour> colour = _content->caption->colour();
        _force_colour->SetValue (static_cast<bool>(colour));
        if (colour) {
                _colour->SetColour (wxColour (colour->r, colour->g, colour->b));
@@ -134,7 +134,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
                _colour->SetColour (wxColour (255, 255, 255));
        }
 
-       optional<dcp::Effect> effect = _content->subtitle->effect();
+       optional<dcp::Effect> effect = _content->caption->effect();
        _force_effect->SetValue (static_cast<bool>(effect));
        if (effect) {
                switch (*effect) {
@@ -152,7 +152,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
                _effect->SetSelection (NONE);
        }
 
-       optional<dcp::Colour> effect_colour = _content->subtitle->effect_colour();
+       optional<dcp::Colour> effect_colour = _content->caption->effect_colour();
        _force_effect_colour->SetValue (static_cast<bool>(effect_colour));
        if (effect_colour) {
                _effect_colour->SetColour (wxColour (effect_colour->r, effect_colour->g, effect_colour->b));
@@ -160,7 +160,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
                _effect_colour->SetColour (wxColour (0, 0, 0));
        }
 
-       optional<ContentTime> fade_in = _content->subtitle->fade_in();
+       optional<ContentTime> fade_in = _content->caption->fade_in();
        _force_fade_in->SetValue (static_cast<bool>(fade_in));
        if (fade_in) {
                _fade_in->set (*fade_in, _content->active_video_frame_rate());
@@ -168,7 +168,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
                _fade_in->set (ContentTime(), _content->active_video_frame_rate());
        }
 
-       optional<ContentTime> fade_out = _content->subtitle->fade_out();
+       optional<ContentTime> fade_out = _content->caption->fade_out();
        _force_fade_out->SetValue (static_cast<bool>(fade_out));
        if (fade_out) {
                _fade_out->set (*fade_out, _content->active_video_frame_rate ());
@@ -176,7 +176,7 @@ SubtitleAppearanceDialog::SubtitleAppearanceDialog (wxWindow* parent, shared_ptr
                _fade_out->set (ContentTime(), _content->active_video_frame_rate ());
        }
 
-       _outline_width->SetValue (_content->subtitle->outline_width ());
+       _outline_width->SetValue (_content->caption->outline_width ());
 
        _force_colour->Bind (wxEVT_CHECKBOX, bind (&SubtitleAppearanceDialog::setup_sensitivity, this));
        _force_effect_colour->Bind (wxEVT_CHECKBOX, bind (&SubtitleAppearanceDialog::setup_sensitivity, this));
@@ -206,42 +206,42 @@ SubtitleAppearanceDialog::apply ()
 {
        if (_force_colour->GetValue ()) {
                wxColour const c = _colour->GetColour ();
-               _content->subtitle->set_colour (dcp::Colour (c.Red(), c.Green(), c.Blue()));
+               _content->caption->set_colour (dcp::Colour (c.Red(), c.Green(), c.Blue()));
        } else {
-               _content->subtitle->unset_colour ();
+               _content->caption->unset_colour ();
        }
        if (_force_effect->GetValue()) {
                switch (_effect->GetSelection()) {
                case NONE:
-                       _content->subtitle->set_effect (dcp::NONE);
+                       _content->caption->set_effect (dcp::NONE);
                        break;
                case OUTLINE:
-                       _content->subtitle->set_effect (dcp::BORDER);
+                       _content->caption->set_effect (dcp::BORDER);
                        break;
                case SHADOW:
-                       _content->subtitle->set_effect (dcp::SHADOW);
+                       _content->caption->set_effect (dcp::SHADOW);
                        break;
                }
        } else {
-               _content->subtitle->unset_effect ();
+               _content->caption->unset_effect ();
        }
        if (_force_effect_colour->GetValue ()) {
                wxColour const ec = _effect_colour->GetColour ();
-               _content->subtitle->set_effect_colour (dcp::Colour (ec.Red(), ec.Green(), ec.Blue()));
+               _content->caption->set_effect_colour (dcp::Colour (ec.Red(), ec.Green(), ec.Blue()));
        } else {
-               _content->subtitle->unset_effect_colour ();
+               _content->caption->unset_effect_colour ();
        }
        if (_force_fade_in->GetValue ()) {
-               _content->subtitle->set_fade_in (_fade_in->get (_content->active_video_frame_rate ()));
+               _content->caption->set_fade_in (_fade_in->get (_content->active_video_frame_rate ()));
        } else {
-               _content->subtitle->unset_fade_in ();
+               _content->caption->unset_fade_in ();
        }
        if (_force_fade_out->GetValue ()) {
-               _content->subtitle->set_fade_out (_fade_out->get (_content->active_video_frame_rate ()));
+               _content->caption->set_fade_out (_fade_out->get (_content->active_video_frame_rate ()));
        } else {
-               _content->subtitle->unset_fade_out ();
+               _content->caption->unset_fade_out ();
        }
-       _content->subtitle->set_outline_width (_outline_width->GetValue ());
+       _content->caption->set_outline_width (_outline_width->GetValue ());
 
        if (_stream) {
                for (map<RGBA, RGBAColourPicker*>::const_iterator i = _pickers.begin(); i != _pickers.end(); ++i) {
@@ -272,11 +272,11 @@ SubtitleAppearanceDialog::setup_sensitivity ()
        _fade_in->Enable (_force_fade_in->GetValue ());
        _fade_out->Enable (_force_fade_out->GetValue ());
 
-       bool const can_outline_width = _effect->GetSelection() == OUTLINE && _content->subtitle->burn ();
+       bool const can_outline_width = _effect->GetSelection() == OUTLINE && _content->caption->burn ();
        _outline_width->Enable (can_outline_width);
        if (can_outline_width) {
                _outline_width->UnsetToolTip ();
        } else {
-               _outline_width->SetToolTip (_("Outline width cannot be set unless you are burning in subtitles"));
+               _outline_width->SetToolTip (_("Outline width cannot be set unless you are burning in captions"));
        }
 }
index f33d6eddf5a432aed0277351a078dc0014b75802..6d34a93db887796cb5e6c287611dc845354e4f90 100644 (file)
 */
 
 #include "lib/text_caption_file_decoder.h"
-#include "lib/content_text.h"
+#include "lib/content_caption.h"
 #include "lib/video_decoder.h"
 #include "lib/audio_decoder.h"
 #include "lib/film.h"
 #include "lib/config.h"
 #include "lib/text_caption_file_content.h"
-#include "lib/text_decoder.h"
+#include "lib/caption_decoder.h"
 #include "subtitle_view.h"
 #include "film_viewer.h"
 #include "wx_util.h"
@@ -85,8 +85,8 @@ SubtitleView::SubtitleView (wxWindow* parent, shared_ptr<Film> film, shared_ptr<
 
        _subs = 0;
        _frc = film->active_frame_rate_change (content->position());
-       decoder->subtitle->PlainStart.connect (bind (&SubtitleView::data_start, this, _1));
-       decoder->subtitle->Stop.connect (bind (&SubtitleView::data_stop, this, _1));
+       decoder->caption->PlainStart.connect (bind (&SubtitleView::data_start, this, _1));
+       decoder->caption->Stop.connect (bind (&SubtitleView::data_stop, this, _1));
        while (!decoder->pass ()) {}
        SetSizerAndFit (sizer);
 }
index 222fc389045de9d43a5ba97277ca3a63d12b9c6d..445f646aa8ef271b68f7b7464c737454a5ee30c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -18,7 +18,7 @@
 
 */
 
-#include "lib/content_text.h"
+#include "lib/content_caption.h"
 #include <boost/shared_ptr.hpp>
 #include <wx/wx.h>
 #include <wx/listctrl.h>
index d0a898b18f645d3d469c997b039f88ed138f78ed..d3b291a9b04a9edd208cc1e77fb99f12cf8b88e2 100644 (file)
@@ -34,7 +34,7 @@
 #include "lib/image_content.h"
 #include "lib/timer.h"
 #include "lib/audio_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/video_content.h"
 #include "lib/atmos_mxf_content.h"
 #include <wx/graphics.h>
@@ -228,7 +228,7 @@ Timeline::recreate_views ()
                        _views.push_back (shared_ptr<TimelineView> (new TimelineAudioContentView (*this, i)));
                }
 
-               if (i->subtitle) {
+               if (i->caption) {
                        _views.push_back (shared_ptr<TimelineView> (new TimelineTextContentView (*this, i)));
                }
 
index b4820bfea8471d4598fe38c60d13663a7c97a325..bb874449ef7321c9795e53a294edaa6bcbf18d0d 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2013-2018 Carl Hetherington <cth@carlh.net>
 
     This file is part of DCP-o-matic.
 
@@ -19,7 +19,7 @@
 */
 
 #include "timeline_text_content_view.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/content.h"
 
 using boost::shared_ptr;
@@ -55,5 +55,5 @@ TimelineTextContentView::active () const
 {
        shared_ptr<Content> c = _content.lock ();
        DCPOMATIC_ASSERT (c);
-       return c->subtitle && c->subtitle->use();
+       return c->caption && c->caption->use();
 }
index 2a97f405f1b4ee35ca9a76985675f802079878a4..9b516ccfa8a7ba9533444e511d067d8dfff56518 100644 (file)
@@ -26,8 +26,8 @@
 #include "move_to_dialog.h"
 #include "lib/content.h"
 #include "lib/image_content.h"
-#include "lib/text_content.h"
-#include "lib/dcp_text_content.h"
+#include "lib/caption_content.h"
+#include "lib/dcp_subtitle_content.h"
 #include "lib/audio_content.h"
 #include "lib/text_caption_file_content.h"
 #include "lib/video_content.h"
@@ -282,7 +282,7 @@ TimingPanel::film_content_changed (int property)
                                ++count_ac;
                                content = i;
                        }
-                       if (i->subtitle && i->video_frame_rate()) {
+                       if (i->caption && i->video_frame_rate()) {
                                ++count_sc;
                                content = i;
                        }
index e5d0408bb82ab5aa4e8ef91ca2b046b6ef539c9c..48f88f8dcbbe534ba1bb6b599a42607003421925 100644 (file)
 
 #include <boost/test/unit_test.hpp>
 #include "lib/film.h"
-#include "lib/dcp_text_content.h"
+#include "lib/dcp_subtitle_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_text_decoder.h"
-#include "lib/text_content.h"
-#include "lib/content_text.h"
+#include "lib/dcp_subtitle_decoder.h"
+#include "lib/caption_content.h"
+#include "lib/content_caption.h"
 #include "lib/font.h"
-#include "lib/text_decoder.h"
+#include "lib/caption_decoder.h"
 #include "test.h"
 #include <iostream>
 
@@ -65,14 +65,14 @@ 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);
-       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub.xml"));
+       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
        BOOST_CHECK_EQUAL (content->full_length().get(), DCPTime::from_seconds(2).get());
 
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
@@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_within_dcp_test)
        BOOST_REQUIRE (!wait_for_jobs ());
 
        shared_ptr<DCPDecoder> decoder (new DCPDecoder (content, film->log(), false));
-       decoder->subtitle->PlainStart.connect (bind (store, _1));
+       decoder->caption->PlainStart.connect (bind (store, _1));
 
        stored = optional<ContentTextCaption> ();
        while (!decoder->pass() && !stored) {}
@@ -109,12 +109,12 @@ 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");
-       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub2.xml"));
+       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub2.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
-       decoder->subtitle->PlainStart.connect (bind (store, _1));
+       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
+       decoder->caption->PlainStart.connect (bind (store, _1));
 
        stored = optional<ContentTextCaption> ();
        while (!decoder->pass ()) {
@@ -132,17 +132,17 @@ 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);
-       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub3.xml"));
+       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (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 ());
 
-       shared_ptr<DCPTextDecoder> decoder (new DCPTextDecoder (content, film->log()));
+       shared_ptr<DCPSubtitleDecoder> decoder (new DCPSubtitleDecoder (content, film->log()));
        stored = optional<ContentTextCaption> ();
        while (!decoder->pass ()) {
-               decoder->subtitle->PlainStart.connect (bind (store, _1));
+               decoder->caption->PlainStart.connect (bind (store, _1));
                if (stored && stored->from() == ContentTime::from_seconds(0.08)) {
                        list<dcp::SubtitleString> s = stored->subs;
                        list<dcp::SubtitleString>::const_iterator i = s.begin ();
@@ -165,14 +165,14 @@ BOOST_AUTO_TEST_CASE (dcp_subtitle_test4)
        shared_ptr<Film> film = new_test_film2 ("dcp_subtitle_test4");
        film->set_interop (true);
 
-       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub3.xml"));
+       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub3.xml"));
        film->examine_and_add_content (content);
-       shared_ptr<DCPTextContent> content2 (new DCPTextContent (film, "test/data/dcp_sub3.xml"));
+       shared_ptr<DCPSubtitleContent> content2 (new DCPSubtitleContent (film, "test/data/dcp_sub3.xml"));
        film->examine_and_add_content (content2);
        BOOST_REQUIRE (!wait_for_jobs ());
 
-       content->subtitle->add_font (shared_ptr<Font> (new Font ("font1")));
-       content2->subtitle->add_font (shared_ptr<Font> (new Font ("font2")));
+       content->caption->add_font (shared_ptr<Font> (new Font ("font1")));
+       content2->caption->add_font (shared_ptr<Font> (new Font ("font2")));
 
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
index 65ca59d349b63cc4204f4bc8ef1e6d020446d0df..d9dd0f3831bacf6a5bc3f55f71b49f72b8bd4118 100644 (file)
@@ -28,7 +28,7 @@
 #include "lib/ratio.h"
 #include "lib/transcode_job.h"
 #include "lib/dcp_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/compose.hpp"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -124,9 +124,9 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test6)
        shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (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));
-       s->subtitle->set_effect (dcp::SHADOW);
-       s->subtitle->set_effect_colour (dcp::Colour (0, 255, 255));
+       s->caption->set_colour (dcp::Colour (255, 255, 0));
+       s->caption->set_effect (dcp::SHADOW);
+       s->caption->set_effect_colour (dcp::Colour (0, 255, 255));
        film->write_metadata();
 
        shared_ptr<Job> job (new TranscodeJob (film));
@@ -149,9 +149,9 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_prores_test7)
        shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (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));
-       s->subtitle->set_effect (dcp::SHADOW);
-       s->subtitle->set_effect_colour (dcp::Colour (0, 255, 255));
+       s->caption->set_colour (dcp::Colour (255, 255, 0));
+       s->caption->set_effect (dcp::SHADOW);
+       s->caption->set_effect_colour (dcp::Colour (0, 255, 255));
 
        shared_ptr<Job> job (new TranscodeJob (film));
        FFmpegEncoder encoder (film, job, "build/test/ffmpeg_encoder_prores_test7.mov", FFmpegEncoder::FORMAT_PRORES, false);
@@ -175,9 +175,9 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test2)
        shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (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));
-       s->subtitle->set_effect (dcp::SHADOW);
-       s->subtitle->set_effect_colour (dcp::Colour (0, 255, 255));
+       s->caption->set_colour (dcp::Colour (255, 255, 0));
+       s->caption->set_effect (dcp::SHADOW);
+       s->caption->set_effect_colour (dcp::Colour (0, 255, 255));
        film->write_metadata();
 
        shared_ptr<Job> job (new TranscodeJob (film));
@@ -200,9 +200,9 @@ BOOST_AUTO_TEST_CASE (ffmpeg_encoder_h264_test3)
        shared_ptr<TextCaptionFileContent> s (new TextCaptionFileContent (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));
-       s->subtitle->set_effect (dcp::SHADOW);
-       s->subtitle->set_effect_colour (dcp::Colour (0, 255, 255));
+       s->caption->set_colour (dcp::Colour (255, 255, 0));
+       s->caption->set_effect (dcp::SHADOW);
+       s->caption->set_effect_colour (dcp::Colour (0, 255, 255));
        film->write_metadata();
 
        shared_ptr<Job> job (new TranscodeJob (film));
index c12f15fa1e726c1c4bc411a69549931a074cdb7d..1f5247392a461b6dd90033b4189a7a18c2f02b7c 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "test.h"
 #include "lib/film.h"
-#include "lib/dcp_text_content.h"
+#include "lib/dcp_subtitle_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"
index d3b6df6da6221d40750ae0f29e8ee1b588a4459b..4ff79b436d0fd2436d123381fc32d560adfdf436 100644 (file)
@@ -34,7 +34,7 @@
 #include "lib/text_caption_file_content.h"
 #include "lib/content_factory.h"
 #include "lib/dcp_content.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/butler.h"
 #include "lib/compose.hpp"
 #include "test.h"
@@ -211,7 +211,7 @@ BOOST_AUTO_TEST_CASE (player_seek_test)
        shared_ptr<DCPContent> dcp (new DCPContent (film, private_data / "awkward_subs"));
        film->examine_and_add_content (dcp, true);
        BOOST_REQUIRE (!wait_for_jobs ());
-       dcp->subtitle->set_use (true);
+       dcp->caption->set_use (true);
 
        shared_ptr<Player> player (new Player (film, film->playlist()));
        player->set_fast ();
@@ -242,7 +242,7 @@ BOOST_AUTO_TEST_CASE (player_seek_test2)
        shared_ptr<DCPContent> dcp (new DCPContent (film, private_data / "awkward_subs2"));
        film->examine_and_add_content (dcp, true);
        BOOST_REQUIRE (!wait_for_jobs ());
-       dcp->subtitle->set_use (true);
+       dcp->caption->set_use (true);
 
        shared_ptr<Player> player (new Player (film, film->playlist()));
        player->set_fast ();
index e7e9c67b2dc3758ef015ce870115637c4bcec7aa..79e12f7a0b85f66d90adbb5e0b400af9193871e9 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/job_manager.h"
 #include "lib/film.h"
 #include "lib/dcp_content.h"
index 4e286523f9259c467f5eebcb6fde3fd7b06ff0b4..5c371e855b03b580c353509464bdc3f0683047d5 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "lib/ffmpeg_content.h"
 #include "lib/content_factory.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/film.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
@@ -37,14 +37,14 @@ BOOST_AUTO_TEST_CASE (remake_with_subtitle_test)
        shared_ptr<FFmpegContent> content = dynamic_pointer_cast<FFmpegContent>(content_factory(film, private_data / "prophet_short_clip.mkv").front());
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
-       content->subtitle->set_burn (true);
-       content->subtitle->set_use (true);
+       content->caption->set_burn (true);
+       content->caption->set_use (true);
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
        boost::filesystem::remove_all (film->dir (film->dcp_name(), false));
 
-       content->subtitle->set_use (false);
+       content->caption->set_use (false);
        film->make_dcp ();
        BOOST_REQUIRE (!wait_for_jobs ());
 
index 6fe430d776f923b641e225bc64107021118a22fa..28ef9606fc487df2a5cc499da34200e3e3beecf8 100644 (file)
@@ -28,7 +28,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
@@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->make_dcp ();
        wait_for_jobs ();
 
@@ -73,10 +73,10 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test2)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        /* Use test/data/subrip2.srt as if it were a font file  */
-       content->subtitle->fonts().front()->set_file (FontFiles::NORMAL, "test/data/subrip2.srt");
+       content->caption->fonts().front()->set_file (FontFiles::NORMAL, "test/data/subrip2.srt");
 
        film->make_dcp ();
        wait_for_jobs ();
@@ -108,8 +108,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test3)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
 
        film->make_dcp ();
        wait_for_jobs ();
@@ -126,8 +126,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
        film->set_name ("frobozz");
        film->set_interop (false);
        shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->examine_and_add_content (content);
        wait_for_jobs ();
        film->make_dcp ();
@@ -147,8 +147,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test5)
        film->set_interop (true);
        film->set_sequence (false);
        shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip2.srt"));
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->examine_and_add_content (content);
        film->examine_and_add_content (content);
        wait_for_jobs ();
@@ -165,8 +165,8 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test6)
        shared_ptr<Film> film = new_test_film2 ("srt_subtitle_test6");
        film->set_interop (false);
        shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/frames.srt"));
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
        film->make_dcp ();
@@ -190,7 +190,7 @@ BOOST_AUTO_TEST_CASE (srt_subtitle_test4)
        BOOST_CHECK_EQUAL (content->full_length(), DCPTime::from_seconds ((3 * 60) + 56.471));
 
        shared_ptr<SubRipDecoder> decoder (new SubRipDecoder (content));
-       list<ContentTextSubtitle> cts = decoder->get_plain_texts (
+       list<ContentTextCaption> cts = decoder->get_plain_texts (
                ContentTimePeriod (
                        ContentTime::from_seconds (109), ContentTime::from_seconds (110)
                        ), false
index b3e4f9d333d789e2b8451ba4129e21e7396f7375..6d4eecd92411e247b965540a834aadbb89940b7a 100644 (file)
@@ -28,7 +28,7 @@
 #include "lib/dcp_content_type.h"
 #include "lib/font.h"
 #include "lib/ratio.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "test.h"
 #include <boost/test/unit_test.hpp>
 #include <boost/algorithm/string.hpp>
@@ -51,8 +51,8 @@ BOOST_AUTO_TEST_CASE (ssa_subtitle_test1)
        film->examine_and_add_content (content);
        wait_for_jobs ();
 
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
 
        film->make_dcp ();
        wait_for_jobs ();
index 3e7df0a61bfd0718de287ff942657e6d92952be0..b15e3e70e403100e14d0b6aa329e89bab951b7a3 100644 (file)
@@ -22,7 +22,7 @@
 #include "lib/content.h"
 #include "lib/film.h"
 #include "lib/content_factory.h"
-#include "lib/plain_text_file.h"
+#include "lib/text_caption_file.h"
 #include "lib/text_caption_file_content.h"
 #include <boost/test/unit_test.hpp>
 
index 27c6e2d0e09d99540cd150ff99efe609a8916d89..a82094a7351e253bb1c7d9904f340c28c9ad0fc9 100644 (file)
@@ -21,7 +21,7 @@
 #include "lib/text_caption_file_content.h"
 #include "lib/film.h"
 #include "lib/ratio.h"
-#include "lib/text_content.h"
+#include "lib/caption_content.h"
 #include "lib/dcp_content_type.h"
 #include "test.h"
 #include <dcp/cpl.h>
@@ -46,8 +46,8 @@ BOOST_AUTO_TEST_CASE (subtitle_reel_number_test)
        shared_ptr<TextCaptionFileContent> content (new TextCaptionFileContent (film, "test/data/subrip5.srt"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
-       content->subtitle->set_use (true);
-       content->subtitle->set_burn (false);
+       content->caption->set_use (true);
+       content->caption->set_burn (false);
        film->set_reel_type (REELTYPE_BY_LENGTH);
        film->set_interop (true);
        film->set_reel_length (1024 * 1024 * 512);
index 1174eb583e513f7d1bb8e82a5a9bf24d38107d0e..33bcf823f2deb69aec1963c58da1f54f778b9d76 100644 (file)
@@ -19,7 +19,7 @@
 */
 
 #include "lib/film.h"
-#include "lib/dcp_text_content.h"
+#include "lib/dcp_subtitle_content.h"
 #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");
-       shared_ptr<DCPTextContent> content (new DCPTextContent (film, "test/data/dcp_sub5.xml"));
+       shared_ptr<DCPSubtitleContent> content (new DCPSubtitleContent (film, "test/data/dcp_sub5.xml"));
        film->examine_and_add_content (content);
        BOOST_REQUIRE (!wait_for_jobs ());
 
index 1ed5ac81061d1167d2269eb83d56dd5fa5084e10..8b6e215bade6e42fdcdfd8161eb67c008898a6e2 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "test.h"
 #include "lib/film.h"
-#include "lib/dcp_text_content.h"
+#include "lib/dcp_subtitle_content.h"
 #include "lib/ratio.h"
 #include "lib/dcp_content_type.h"
 #include "lib/dcp_content.h"