diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-12-14 22:44:23 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-12-14 22:44:23 +0000 |
| commit | 861117816d557cd048d56b26f8903ac26a94b395 (patch) | |
| tree | 269649a3b7e3ed2f3f6dedd46e167921da388958 /src | |
| parent | e58cec97a15d1d5dd198dfb145e1d7daf6be9641 (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.cc | 7 | ||||
| -rw-r--r-- | src/interop_load_font.cc (renamed from src/load_font.cc) | 6 | ||||
| -rw-r--r-- | src/interop_load_font.h | 39 | ||||
| -rw-r--r-- | src/interop_subtitle_content.cc | 170 | ||||
| -rw-r--r-- | src/interop_subtitle_content.h | 40 | ||||
| -rw-r--r-- | src/smpte_load_font.cc | 31 | ||||
| -rw-r--r-- | src/smpte_load_font.h (renamed from src/load_font.h) | 8 | ||||
| -rw-r--r-- | src/smpte_subtitle_content.cc | 63 | ||||
| -rw-r--r-- | src/smpte_subtitle_content.h | 36 | ||||
| -rw-r--r-- | src/subtitle_content.cc | 200 | ||||
| -rw-r--r-- | src/subtitle_content.h | 37 | ||||
| -rw-r--r-- | src/subtitle_string.cc | 5 | ||||
| -rw-r--r-- | src/subtitle_string.h | 11 | ||||
| -rw-r--r-- | src/wscript | 5 |
14 files changed, 424 insertions, 234 deletions
@@ -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 |
