summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2014-12-14 22:44:23 +0000
committerCarl Hetherington <cth@carlh.net>2014-12-14 22:44:23 +0000
commit861117816d557cd048d56b26f8903ac26a94b395 (patch)
tree269649a3b7e3ed2f3f6dedd46e167921da388958 /src
parente58cec97a15d1d5dd198dfb145e1d7daf6be9641 (diff)
Switch subtitle string font specs to be the font ID; split SubtitleContent into Interop and SMPTE.
Diffstat (limited to 'src')
-rw-r--r--src/dcp.cc7
-rw-r--r--src/interop_load_font.cc (renamed from src/load_font.cc)6
-rw-r--r--src/interop_load_font.h39
-rw-r--r--src/interop_subtitle_content.cc170
-rw-r--r--src/interop_subtitle_content.h40
-rw-r--r--src/smpte_load_font.cc31
-rw-r--r--src/smpte_load_font.h (renamed from src/load_font.h)8
-rw-r--r--src/smpte_subtitle_content.cc63
-rw-r--r--src/smpte_subtitle_content.h36
-rw-r--r--src/subtitle_content.cc200
-rw-r--r--src/subtitle_content.h37
-rw-r--r--src/subtitle_string.cc5
-rw-r--r--src/subtitle_string.h11
-rw-r--r--src/wscript5
14 files changed, 424 insertions, 234 deletions
diff --git a/src/dcp.cc b/src/dcp.cc
index 58b6c66f..b1443e1a 100644
--- a/src/dcp.cc
+++ b/src/dcp.cc
@@ -25,7 +25,8 @@
#include "dcp.h"
#include "sound_mxf.h"
#include "picture_mxf.h"
-#include "subtitle_content.h"
+#include "interop_subtitle_content.h"
+#include "smpte_subtitle_content.h"
#include "mono_picture_mxf.h"
#include "stereo_picture_mxf.h"
#include "util.h"
@@ -132,7 +133,7 @@ DCP::read (bool keep_going, ReadErrors* errors)
if (root == "CompositionPlaylist") {
_assets.push_back (shared_ptr<CPL> (new CPL (path)));
} else if (root == "DCSubtitle") {
- _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path, false)));
+ _assets.push_back (shared_ptr<InteropSubtitleContent> (new InteropSubtitleContent (path)));
}
} else if (boost::algorithm::ends_with (path.string(), ".mxf")) {
ASDCP::EssenceType_t type;
@@ -154,7 +155,7 @@ DCP::read (bool keep_going, ReadErrors* errors)
_assets.push_back (shared_ptr<StereoPictureMXF> (new StereoPictureMXF (path)));
break;
case ASDCP::ESS_TIMED_TEXT:
- _assets.push_back (shared_ptr<SubtitleContent> (new SubtitleContent (path, true)));
+ _assets.push_back (shared_ptr<SMPTESubtitleContent> (new SMPTESubtitleContent (path)));
break;
default:
throw DCPReadError ("Unknown MXF essence type");
diff --git a/src/load_font.cc b/src/interop_load_font.cc
index b46569c8..ec2653ef 100644
--- a/src/load_font.cc
+++ b/src/interop_load_font.cc
@@ -17,7 +17,7 @@
*/
-#include "load_font.h"
+#include "interop_load_font.h"
#include <libcxml/cxml.h>
using std::string;
@@ -25,7 +25,7 @@ using boost::shared_ptr;
using boost::optional;
using namespace dcp;
-LoadFont::LoadFont (boost::shared_ptr<const cxml::Node> node)
+InteropLoadFont::InteropLoadFont (shared_ptr<const cxml::Node> node)
{
optional<string> x = node->optional_string_attribute ("Id");
if (!x) {
@@ -33,5 +33,5 @@ LoadFont::LoadFont (boost::shared_ptr<const cxml::Node> node)
}
id = x.get_value_or ("");
- uri = node->optional_string_attribute ("URI");
+ uri = node->string_attribute ("URI");
}
diff --git a/src/interop_load_font.h b/src/interop_load_font.h
new file mode 100644
index 00000000..b6043bd0
--- /dev/null
+++ b/src/interop_load_font.h
@@ -0,0 +1,39 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/shared_ptr.hpp>
+#include <boost/optional.hpp>
+
+namespace cxml {
+ class Node;
+}
+
+namespace dcp {
+
+class InteropLoadFont
+{
+public:
+ InteropLoadFont () {}
+ InteropLoadFont (boost::shared_ptr<const cxml::Node> node);
+
+ std::string id;
+ std::string uri;
+};
+
+}
diff --git a/src/interop_subtitle_content.cc b/src/interop_subtitle_content.cc
new file mode 100644
index 00000000..85e52da7
--- /dev/null
+++ b/src/interop_subtitle_content.cc
@@ -0,0 +1,170 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "interop_subtitle_content.h"
+#include "interop_load_font.h"
+#include "xml.h"
+#include "raw_convert.h"
+#include "font.h"
+
+using std::list;
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+InteropSubtitleContent::InteropSubtitleContent (boost::filesystem::path file)
+ : SubtitleContent (file)
+{
+ shared_ptr<cxml::Document> xml (new cxml::Document ("DCSubtitle"));
+ xml->read_file (file);
+ _id = xml->string_child ("SubtitleID");
+
+ _movie_title = xml->string_child ("MovieTitle");
+
+ _load_font_nodes = type_children<dcp::InteropLoadFont> (xml, "LoadFont");
+ list<shared_ptr<dcp::Font> > font_nodes = type_children<dcp::Font> (xml, "Font");
+
+ parse_common (xml, font_nodes);
+}
+
+InteropSubtitleContent::InteropSubtitleContent (string movie_title, string language)
+ : _movie_title (movie_title)
+{
+ _language = language;
+}
+
+struct SubtitleSorter {
+ bool operator() (SubtitleString const & a, SubtitleString const & b) {
+ if (a.in() != b.in()) {
+ return a.in() < b.in();
+ }
+ return a.v_position() < b.v_position();
+ }
+};
+
+Glib::ustring
+InteropSubtitleContent::xml_as_string () const
+{
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
+ root->set_attribute ("Version", "1.0");
+
+ root->add_child("SubtitleID")->add_child_text (_id);
+ root->add_child("MovieTitle")->add_child_text (_movie_title);
+ root->add_child("ReelNumber")->add_child_text (raw_convert<string> (_reel_number));
+ root->add_child("Language")->add_child_text (_language);
+
+ if (_load_font_nodes.size() > 1) {
+ boost::throw_exception (MiscError ("multiple LoadFont nodes not supported"));
+ }
+
+ if (!_load_font_nodes.empty ()) {
+ xmlpp::Element* load_font = root->add_child("LoadFont");
+ load_font->set_attribute ("Id", _load_font_nodes.front()->id);
+ load_font->set_attribute ("URI", _load_font_nodes.front()->uri);
+ }
+
+ list<SubtitleString> sorted = _subtitles;
+ sorted.sort (SubtitleSorter ());
+
+ /* XXX: multiple fonts not supported */
+ /* XXX: script, underlined, weight not supported */
+
+ bool italic = false;
+ Color color;
+ int size = 0;
+ Effect effect = NONE;
+ Color effect_color;
+ int spot_number = 1;
+ Time last_in;
+ Time last_out;
+ Time last_fade_up_time;
+ Time last_fade_down_time;
+
+ xmlpp::Element* font = 0;
+ xmlpp::Element* subtitle = 0;
+
+ for (list<SubtitleString>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
+
+ /* We will start a new <Font>...</Font> whenever some font property changes.
+ I suppose we should really make an optimal hierarchy of <Font> tags, but
+ that seems hard.
+ */
+
+ bool const font_changed =
+ italic != i->italic() ||
+ color != i->color() ||
+ size != i->size() ||
+ effect != i->effect() ||
+ effect_color != i->effect_color();
+
+ if (font_changed) {
+ italic = i->italic ();
+ color = i->color ();
+ size = i->size ();
+ effect = i->effect ();
+ effect_color = i->effect_color ();
+ }
+
+ if (!font || font_changed) {
+ font = root->add_child ("Font");
+ string id = "theFontId";
+ if (!_load_font_nodes.empty()) {
+ id = _load_font_nodes.front()->id;
+ }
+ font->set_attribute ("Id", id);
+ font->set_attribute ("Italic", italic ? "yes" : "no");
+ font->set_attribute ("Color", color.to_argb_string());
+ font->set_attribute ("Size", raw_convert<string> (size));
+ font->set_attribute ("Effect", effect_to_string (effect));
+ font->set_attribute ("EffectColor", effect_color.to_argb_string());
+ font->set_attribute ("Script", "normal");
+ font->set_attribute ("Underlined", "no");
+ font->set_attribute ("Weight", "normal");
+ }
+
+ if (!subtitle || font_changed ||
+ (last_in != i->in() ||
+ last_out != i->out() ||
+ last_fade_up_time != i->fade_up_time() ||
+ last_fade_down_time != i->fade_down_time()
+ )) {
+
+ subtitle = font->add_child ("Subtitle");
+ subtitle->set_attribute ("SpotNumber", raw_convert<string> (spot_number++));
+ subtitle->set_attribute ("TimeIn", i->in().to_string());
+ subtitle->set_attribute ("TimeOut", i->out().to_string());
+ subtitle->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().to_ticks()));
+ subtitle->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().to_ticks()));
+
+ last_in = i->in ();
+ last_out = i->out ();
+ last_fade_up_time = i->fade_up_time ();
+ last_fade_down_time = i->fade_down_time ();
+ }
+
+ xmlpp::Element* text = subtitle->add_child ("Text");
+ text->set_attribute ("VAlign", valign_to_string (i->v_align()));
+ text->set_attribute ("VPosition", raw_convert<string> (i->v_position()));
+ text->add_child_text (i->text());
+ }
+
+ return doc.write_to_string_formatted ("UTF-8");
+}
+
diff --git a/src/interop_subtitle_content.h b/src/interop_subtitle_content.h
new file mode 100644
index 00000000..cd8d7bbd
--- /dev/null
+++ b/src/interop_subtitle_content.h
@@ -0,0 +1,40 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "subtitle_content.h"
+#include <boost/filesystem.hpp>
+
+namespace dcp {
+
+class InteropLoadFont;
+
+class InteropSubtitleContent : public SubtitleContent
+{
+public:
+ InteropSubtitleContent (std::string movie_title, std::string language);
+ InteropSubtitleContent (boost::filesystem::path file);
+
+ Glib::ustring xml_as_string () const;
+
+private:
+ std::string _movie_title;
+ std::list<boost::shared_ptr<InteropLoadFont> > _load_font_nodes;
+};
+
+}
diff --git a/src/smpte_load_font.cc b/src/smpte_load_font.cc
new file mode 100644
index 00000000..90e9c993
--- /dev/null
+++ b/src/smpte_load_font.cc
@@ -0,0 +1,31 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "smpte_load_font.h"
+#include <libcxml/cxml.h>
+
+using std::string;
+using boost::shared_ptr;
+using namespace dcp;
+
+SMPTELoadFont::SMPTELoadFont (shared_ptr<const cxml::Node> node)
+{
+ id = node->string_attribute ("ID");
+ urn = node->content().substr (9);
+}
diff --git a/src/load_font.h b/src/smpte_load_font.h
index 6d52a509..d8d1fa66 100644
--- a/src/load_font.h
+++ b/src/smpte_load_font.h
@@ -26,14 +26,14 @@ namespace cxml {
namespace dcp {
-class LoadFont
+class SMPTELoadFont
{
public:
- LoadFont () {}
- LoadFont (boost::shared_ptr<const cxml::Node> node);
+ SMPTELoadFont () {}
+ SMPTELoadFont (boost::shared_ptr<const cxml::Node> node);
std::string id;
- boost::optional<std::string> uri;
+ std::string urn;
};
}
diff --git a/src/smpte_subtitle_content.cc b/src/smpte_subtitle_content.cc
new file mode 100644
index 00000000..1fa94d1c
--- /dev/null
+++ b/src/smpte_subtitle_content.cc
@@ -0,0 +1,63 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "smpte_subtitle_content.h"
+#include "smpte_load_font.h"
+#include "font.h"
+#include "exceptions.h"
+#include "xml.h"
+#include "AS_DCP.h"
+#include "KM_util.h"
+
+using std::string;
+using std::list;
+using std::stringstream;
+using boost::shared_ptr;
+using namespace dcp;
+
+SMPTESubtitleContent::SMPTESubtitleContent (boost::filesystem::path file)
+ : SubtitleContent (file)
+{
+ ASDCP::TimedText::MXFReader reader;
+ Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
+ if (ASDCP_FAILURE (r)) {
+ boost::throw_exception (MXFFileError ("could not open MXF file for reading", file, r));
+ }
+
+ string s;
+ reader.ReadTimedTextResource (s, 0, 0);
+ shared_ptr<cxml::Document> xml (new cxml::Document ("SubtitleReel"));
+ stringstream t;
+ t << s;
+ xml->read_stream (t);
+
+ ASDCP::WriterInfo info;
+ reader.FillWriterInfo (info);
+
+ char buffer[64];
+ Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer));
+ _id = buffer;
+
+ _load_font_nodes = type_children<dcp::SMPTELoadFont> (xml, "LoadFont");
+
+ shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
+ list<shared_ptr<dcp::Font> > font_nodes = type_children<dcp::Font> (subtitle_list, "Font");
+
+ parse_common (xml, font_nodes);
+}
diff --git a/src/smpte_subtitle_content.h b/src/smpte_subtitle_content.h
new file mode 100644
index 00000000..b760f727
--- /dev/null
+++ b/src/smpte_subtitle_content.h
@@ -0,0 +1,36 @@
+/*
+ Copyright (C) 2012-2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include "subtitle_content.h"
+
+namespace dcp {
+
+class SMPTELoadFont;
+
+class SMPTESubtitleContent : public SubtitleContent
+{
+public:
+ /** @param file MXF file */
+ SMPTESubtitleContent (boost::filesystem::path file);
+
+private:
+ std::list<boost::shared_ptr<SMPTELoadFont> > _load_font_nodes;
+};
+
+}
diff --git a/src/subtitle_content.cc b/src/subtitle_content.cc
index 4f83d5bd..7bc080b3 100644
--- a/src/subtitle_content.cc
+++ b/src/subtitle_content.cc
@@ -23,7 +23,6 @@
#include "xml.h"
#include "font.h"
#include "text.h"
-#include "load_font.h"
#include "subtitle_string.h"
#include "AS_DCP.h"
#include "KM_util.h"
@@ -41,71 +40,26 @@ using boost::shared_ptr;
using boost::optional;
using namespace dcp;
-SubtitleContent::SubtitleContent (boost::filesystem::path file, bool mxf)
+SubtitleContent::SubtitleContent (boost::filesystem::path file)
: Content (file)
{
- shared_ptr<cxml::Document> xml;
-
- if (mxf) {
- ASDCP::TimedText::MXFReader reader;
- Kumu::Result_t r = reader.OpenRead (file.string().c_str ());
- if (ASDCP_FAILURE (r)) {
- boost::throw_exception (MXFFileError ("could not open MXF file for reading", file, r));
- }
-
- string s;
- reader.ReadTimedTextResource (s, 0, 0);
- xml.reset (new cxml::Document ("SubtitleReel"));
- stringstream t;
- t << s;
- xml->read_stream (t);
-
- ASDCP::WriterInfo info;
- reader.FillWriterInfo (info);
-
- char buffer[64];
- Kumu::bin2UUIDhex (info.AssetUUID, ASDCP::UUIDlen, buffer, sizeof (buffer));
- _id = buffer;
-
- } else {
- xml.reset (new cxml::Document ("DCSubtitle"));
- xml->read_file (file);
- _id = xml->string_child ("SubtitleID");
- }
- /* XXX: hacks aplenty in here; probably need separate parsers for DCSubtitle and SubtitleReel */
+}
- _movie_title = xml->optional_string_child ("MovieTitle");
+void
+SubtitleContent::parse_common (shared_ptr<cxml::Document> xml, list<shared_ptr<dcp::Font> > font_nodes)
+{
_reel_number = xml->string_child ("ReelNumber");
_language = xml->string_child ("Language");
- xml->ignore_child ("LoadFont");
-
- list<shared_ptr<dcp::Font> > font_nodes = type_children<dcp::Font> (xml, "Font");
- _load_font_nodes = type_children<dcp::LoadFont> (xml, "LoadFont");
-
/* Now make Subtitle objects to represent the raw XML nodes
in a sane way.
*/
- shared_ptr<cxml::Node> subtitle_list = xml->optional_node_child ("SubtitleList");
- if (subtitle_list) {
- list<shared_ptr<dcp::Font> > font = type_children<dcp::Font> (subtitle_list, "Font");
- copy (font.begin(), font.end(), back_inserter (font_nodes));
- }
-
ParseState parse_state;
examine_font_nodes (xml, font_nodes, parse_state);
}
-SubtitleContent::SubtitleContent (string movie_title, string language)
- : _movie_title (movie_title)
- , _reel_number ("1")
- , _language (language)
-{
-
-}
-
void
SubtitleContent::examine_font_nodes (
shared_ptr<const cxml::Node> xml,
@@ -167,7 +121,7 @@ SubtitleContent::maybe_add_subtitle (string text, ParseState const & parse_state
_subtitles.push_back (
SubtitleString (
- font_id_to_name (effective_font.id),
+ effective_font.id,
effective_font.italic.get(),
effective_font.color.get(),
effective_font.size,
@@ -197,40 +151,12 @@ SubtitleContent::subtitles_at (Time t) const
return s;
}
-std::string
-SubtitleContent::font_id_to_name (string id) const
-{
- list<shared_ptr<dcp::LoadFont> >::const_iterator i = _load_font_nodes.begin();
- while (i != _load_font_nodes.end() && (*i)->id != id) {
- ++i;
- }
-
- if (i == _load_font_nodes.end ()) {
- return "";
- }
-
- if ((*i)->uri && (*i)->uri.get() == "arial.ttf") {
- return "Arial";
- }
-
- return "";
-}
-
void
SubtitleContent::add (SubtitleString s)
{
_subtitles.push_back (s);
}
-struct SubtitleSorter {
- bool operator() (SubtitleString const & a, SubtitleString const & b) {
- if (a.in() != b.in()) {
- return a.in() < b.in();
- }
- return a.v_position() < b.v_position();
- }
-};
-
void
SubtitleContent::write_xml (boost::filesystem::path p) const
{
@@ -246,120 +172,6 @@ SubtitleContent::write_xml (boost::filesystem::path p) const
_file = p;
}
-Glib::ustring
-SubtitleContent::xml_as_string () const
-{
- xmlpp::Document doc;
- xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
- root->set_attribute ("Version", "1.0");
-
- root->add_child("SubtitleID")->add_child_text (_id);
- if (_movie_title) {
- root->add_child("MovieTitle")->add_child_text (_movie_title.get ());
- }
- root->add_child("ReelNumber")->add_child_text (raw_convert<string> (_reel_number));
- root->add_child("Language")->add_child_text (_language);
-
- if (_load_font_nodes.size() > 1) {
- boost::throw_exception (MiscError ("multiple LoadFont nodes not supported"));
- }
-
- if (!_load_font_nodes.empty ()) {
- xmlpp::Element* load_font = root->add_child("LoadFont");
- load_font->set_attribute ("Id", _load_font_nodes.front()->id);
- if (_load_font_nodes.front()->uri) {
- load_font->set_attribute ("URI", _load_font_nodes.front()->uri.get ());
- }
- }
-
- list<SubtitleString> sorted = _subtitles;
- sorted.sort (SubtitleSorter ());
-
- /* XXX: multiple fonts not supported */
- /* XXX: script, underlined, weight not supported */
-
- bool italic = false;
- Color color;
- int size = 0;
- Effect effect = NONE;
- Color effect_color;
- int spot_number = 1;
- Time last_in;
- Time last_out;
- Time last_fade_up_time;
- Time last_fade_down_time;
-
- xmlpp::Element* font = 0;
- xmlpp::Element* subtitle = 0;
-
- for (list<SubtitleString>::iterator i = sorted.begin(); i != sorted.end(); ++i) {
-
- /* We will start a new <Font>...</Font> whenever some font property changes.
- I suppose we should really make an optimal hierarchy of <Font> tags, but
- that seems hard.
- */
-
- bool const font_changed =
- italic != i->italic() ||
- color != i->color() ||
- size != i->size() ||
- effect != i->effect() ||
- effect_color != i->effect_color();
-
- if (font_changed) {
- italic = i->italic ();
- color = i->color ();
- size = i->size ();
- effect = i->effect ();
- effect_color = i->effect_color ();
- }
-
- if (!font || font_changed) {
- font = root->add_child ("Font");
- string id = "theFontId";
- if (!_load_font_nodes.empty()) {
- id = _load_font_nodes.front()->id;
- }
- font->set_attribute ("Id", id);
- font->set_attribute ("Italic", italic ? "yes" : "no");
- font->set_attribute ("Color", color.to_argb_string());
- font->set_attribute ("Size", raw_convert<string> (size));
- font->set_attribute ("Effect", effect_to_string (effect));
- font->set_attribute ("EffectColor", effect_color.to_argb_string());
- font->set_attribute ("Script", "normal");
- font->set_attribute ("Underlined", "no");
- font->set_attribute ("Weight", "normal");
- }
-
- if (!subtitle || font_changed ||
- (last_in != i->in() ||
- last_out != i->out() ||
- last_fade_up_time != i->fade_up_time() ||
- last_fade_down_time != i->fade_down_time()
- )) {
-
- subtitle = font->add_child ("Subtitle");
- subtitle->set_attribute ("SpotNumber", raw_convert<string> (spot_number++));
- subtitle->set_attribute ("TimeIn", i->in().to_string());
- subtitle->set_attribute ("TimeOut", i->out().to_string());
- subtitle->set_attribute ("FadeUpTime", raw_convert<string> (i->fade_up_time().to_ticks()));
- subtitle->set_attribute ("FadeDownTime", raw_convert<string> (i->fade_down_time().to_ticks()));
-
- last_in = i->in ();
- last_out = i->out ();
- last_fade_up_time = i->fade_up_time ();
- last_fade_down_time = i->fade_down_time ();
- }
-
- xmlpp::Element* text = subtitle->add_child ("Text");
- text->set_attribute ("VAlign", valign_to_string (i->v_align()));
- text->set_attribute ("VPosition", raw_convert<string> (i->v_position()));
- text->add_child_text (i->text());
- }
-
- return doc.write_to_string_formatted ("UTF-8");
-}
-
Time
SubtitleContent::latest_subtitle_out () const
{
diff --git a/src/subtitle_content.h b/src/subtitle_content.h
index 945eb4d0..222d52cc 100644
--- a/src/subtitle_content.h
+++ b/src/subtitle_content.h
@@ -32,23 +32,15 @@ class SubtitleString;
class Font;
class Text;
class Subtitle;
-class LoadFont;
/** @class SubtitleContent
- * @brief A representation of an XML or MXF file containing subtitles.
- *
- * XXX: perhaps this should inhert from MXF, or there should be different
- * classes for XML and MXF subs.
+ * @brief A parent for classes representing a file containing subtitles.
*/
class SubtitleContent : public Content
{
public:
- /** Construct a SubtitleContent.
- * @param file Filename.
- * @param mxf true if the file is an MXF file, false for XML.
- */
- SubtitleContent (boost::filesystem::path file, bool mxf);
- SubtitleContent (std::string movie_title, std::string language);
+ SubtitleContent () {}
+ SubtitleContent (boost::filesystem::path file);
bool equals (
boost::shared_ptr<const Asset>,
@@ -72,11 +64,16 @@ public:
void add (SubtitleString);
void write_xml (boost::filesystem::path) const;
- Glib::ustring xml_as_string () const;
+ virtual Glib::ustring xml_as_string () const {
+ /* XXX: this should be pure virtual when SMPTE writing is implemented */
+ return "";
+ }
Time latest_subtitle_out () const;
protected:
+ void parse_common (boost::shared_ptr<cxml::Document> xml, std::list<boost::shared_ptr<dcp::Font> > font_nodes);
+
std::string pkl_type (Standard) const {
return "text/xml";
}
@@ -85,9 +82,13 @@ protected:
return "Subtitle";
}
-private:
- std::string font_id_to_name (std::string id) const;
+ /* strangely, this is sometimes a string */
+ std::string _reel_number;
+ std::string _language;
+
+ std::list<SubtitleString> _subtitles;
+private:
struct ParseState {
std::list<boost::shared_ptr<Font> > font_nodes;
std::list<boost::shared_ptr<Text> > text_nodes;
@@ -107,14 +108,6 @@ private:
std::list<boost::shared_ptr<Text> > const & text_nodes,
ParseState& parse_state
);
-
- boost::optional<std::string> _movie_title;
- /* strangely, this is sometimes a string */
- std::string _reel_number;
- std::string _language;
- std::list<boost::shared_ptr<LoadFont> > _load_font_nodes;
-
- std::list<SubtitleString> _subtitles;
};
}
diff --git a/src/subtitle_string.cc b/src/subtitle_string.cc
index 66869fd5..a92eac92 100644
--- a/src/subtitle_string.cc
+++ b/src/subtitle_string.cc
@@ -22,10 +22,11 @@
using std::string;
using std::ostream;
+using boost::optional;
using namespace dcp;
SubtitleString::SubtitleString (
- string font,
+ optional<string> font,
bool italic,
Color color,
int size,
@@ -92,7 +93,7 @@ dcp::operator<< (ostream& s, SubtitleString const & sub)
{
s << "\n`" << sub.text() << "' from " << sub.in() << " to " << sub.out() << ";\n"
<< "fade up " << sub.fade_up_time() << ", fade down " << sub.fade_down_time() << ";\n"
- << "font " << sub.font() << ", ";
+ << "font " << sub.font().get_value_or ("[default]") << ", ";
if (sub.italic()) {
s << "italic";
diff --git a/src/subtitle_string.h b/src/subtitle_string.h
index b313e82b..512a1b5b 100644
--- a/src/subtitle_string.h
+++ b/src/subtitle_string.h
@@ -26,6 +26,7 @@
#include "types.h"
#include "dcp_time.h"
+#include <boost/optional.hpp>
#include <string>
namespace dcp {
@@ -37,7 +38,7 @@ class SubtitleString
{
public:
SubtitleString (
- std::string font,
+ boost::optional<std::string> font,
bool italic,
Color color,
int size,
@@ -52,8 +53,8 @@ public:
Time fade_down_time
);
- /** @return font name */
- std::string font () const {
+ /** @return font ID */
+ boost::optional<std::string> font () const {
return _font;
}
@@ -122,8 +123,8 @@ public:
}
private:
- /** font name */
- std::string _font;
+ /** font ID */
+ boost::optional<std::string> _font;
/** true if the text is italic */
bool _italic;
/** text colour */
diff --git a/src/wscript b/src/wscript
index 6145a5cd..6b030e35 100644
--- a/src/wscript
+++ b/src/wscript
@@ -29,8 +29,9 @@ def build(bld):
font.cc
gamma_lut.cc
image.cc
+ interop_load_font.cc
+ interop_subtitle_content.cc
key.cc
- load_font.cc
local_time.cc
metadata.cc
mono_picture_mxf.cc
@@ -51,6 +52,8 @@ def build(bld):
reel_subtitle_asset.cc
rgb_xyz.cc
signer.cc
+ smpte_load_font.cc
+ smpte_subtitle_content.cc
sound_mxf.cc
sound_mxf_writer.cc
sound_frame.cc