diff options
| author | Carl Hetherington <cth@carlh.net> | 2012-08-21 16:00:16 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2012-08-21 16:00:16 +0100 |
| commit | f902811342bb9f72bb11e2658aea14cfe8b04c64 (patch) | |
| tree | 542b519f20bca1aae38f6f77dbc3de895699bd9f | |
| parent | 3053ecfbb9d50a07593ebd4cebdb0de5ca0ca88e (diff) | |
Recursively scan font tags in subtitles.
| -rw-r--r-- | src/subtitle_asset.cc | 81 | ||||
| -rw-r--r-- | src/subtitle_asset.h | 7 | ||||
| -rw-r--r-- | src/xml.cc | 11 | ||||
| -rw-r--r-- | src/xml.h | 1 | ||||
| -rw-r--r-- | test/tests.cc | 50 |
5 files changed, 94 insertions, 56 deletions
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc index 8f0c48ab..be036856 100644 --- a/src/subtitle_asset.cc +++ b/src/subtitle_asset.cc @@ -35,38 +35,79 @@ SubtitleAsset::SubtitleAsset (string directory, string xml) ignore_node ("LoadFont"); list<shared_ptr<FontNode> > font_nodes = sub_nodes<FontNode> ("Font"); - list<shared_ptr<LoadFontNode> > load_font_nodes = sub_nodes<LoadFontNode> ("LoadFont"); + _load_font_nodes = sub_nodes<LoadFontNode> ("LoadFont"); /* Now make Subtitle objects to represent the raw XML nodes in a sane way. */ + list<shared_ptr<FontNode> > current_font_nodes; for (list<shared_ptr<FontNode> >::iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) { - for (list<shared_ptr<SubtitleNode> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) { - for (list<shared_ptr<TextNode> >::iterator k = (*j)->text_nodes.begin(); k != (*j)->text_nodes.end(); ++k) { - _subtitles.push_back ( - shared_ptr<Subtitle> ( - new Subtitle ( - font_id_to_name ((*i)->id, load_font_nodes), - (*i)->size, - (*j)->in, - (*j)->out, - (*k)->v_position, - (*k)->text - ) + examine_font_node (*i, current_font_nodes); + } +} + +void +SubtitleAsset::examine_font_node (shared_ptr<FontNode> font_node, list<shared_ptr<FontNode> >& current_font_nodes) +{ + current_font_nodes.push_back (font_node); + + for (list<shared_ptr<SubtitleNode> >::iterator j = font_node->subtitle_nodes.begin(); j != font_node->subtitle_nodes.end(); ++j) { + for (list<shared_ptr<TextNode> >::iterator k = (*j)->text_nodes.begin(); k != (*j)->text_nodes.end(); ++k) { + _subtitles.push_back ( + shared_ptr<Subtitle> ( + new Subtitle ( + font_id_to_name (id_from_font_nodes (current_font_nodes)), + size_from_font_nodes (current_font_nodes), + (*j)->in, + (*j)->out, + (*k)->v_position, + (*k)->text ) - ); - } + ) + ); } } + + for (list<shared_ptr<FontNode> >::iterator j = font_node->font_nodes.begin(); j != font_node->font_nodes.end(); ++j) { + examine_font_node (*j, current_font_nodes); + } + + current_font_nodes.pop_back (); +} + +string +SubtitleAsset::id_from_font_nodes (list<shared_ptr<FontNode> > const & font_nodes) const +{ + for (list<shared_ptr<FontNode> >::const_reverse_iterator i = font_nodes.rbegin(); i != font_nodes.rend(); ++i) { + if (!(*i)->id.empty ()) { + return (*i)->id; + } + } + + return ""; +} + +int +SubtitleAsset::size_from_font_nodes (list<shared_ptr<FontNode> > const & font_nodes) const +{ + for (list<shared_ptr<FontNode> >::const_reverse_iterator i = font_nodes.rbegin(); i != font_nodes.rend(); ++i) { + if ((*i)->size != 0) { + return (*i)->size; + } + } + + return 0; + } FontNode::FontNode (xmlpp::Node const * node) : XMLNode (node) { id = string_attribute ("Id"); - size = int64_attribute ("Size"); + size = optional_int64_attribute ("Size"); subtitle_nodes = sub_nodes<SubtitleNode> ("Subtitle"); + font_nodes = sub_nodes<FontNode> ("Font"); } LoadFontNode::LoadFontNode (xmlpp::Node const * node) @@ -106,14 +147,14 @@ SubtitleAsset::subtitles_at (Time t) const } std::string -SubtitleAsset::font_id_to_name (string id, list<shared_ptr<LoadFontNode> > const & load_font_nodes) const +SubtitleAsset::font_id_to_name (string id) const { - list<shared_ptr<LoadFontNode> >::const_iterator i = load_font_nodes.begin(); - while (i != load_font_nodes.end() && (*i)->id != id) { + list<shared_ptr<LoadFontNode> >::const_iterator i = _load_font_nodes.begin(); + while (i != _load_font_nodes.end() && (*i)->id != id) { ++i; } - if (i == load_font_nodes.end ()) { + if (i == _load_font_nodes.end ()) { return ""; } diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h index 038ff1fa..6a04bed3 100644 --- a/src/subtitle_asset.h +++ b/src/subtitle_asset.h @@ -55,6 +55,7 @@ public: int size; std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes; + std::list<boost::shared_ptr<FontNode> > font_nodes; }; class LoadFontNode : public XMLNode @@ -128,12 +129,16 @@ public: std::list<boost::shared_ptr<Subtitle> > subtitles_at (Time t) const; private: - std::string font_id_to_name (std::string id, std::list<boost::shared_ptr<LoadFontNode> > const & load_font_nodes) const; + std::string font_id_to_name (std::string id) const; + void examine_font_node (boost::shared_ptr<FontNode> font_node, std::list<boost::shared_ptr<FontNode> >& current_font_nodes); + std::string id_from_font_nodes (std::list<boost::shared_ptr<FontNode> > const & font_nodes) const; + int size_from_font_nodes (std::list<boost::shared_ptr<FontNode> > const & font_nodes) const; std::string _subtitle_id; std::string _movie_title; int64_t _reel_number; std::string _language; + std::list<boost::shared_ptr<LoadFontNode> > _load_font_nodes; std::list<boost::shared_ptr<Subtitle> > _subtitles; }; @@ -163,6 +163,17 @@ XMLNode::int64_attribute (string name) return lexical_cast<int64_t> (string_attribute (name)); } +int64_t +XMLNode::optional_int64_attribute (string name) +{ + string const s = string_attribute (name); + if (s.empty ()) { + return 0; + } + + return lexical_cast<int64_t> (s); +} + void XMLNode::done () { @@ -38,6 +38,7 @@ protected: float float_attribute (std::string); std::string string_attribute (std::string); int64_t int64_attribute (std::string); + int64_t optional_int64_attribute (std::string); std::string content (); diff --git a/test/tests.cc b/test/tests.cc index 3d56c3e7..486db0bd 100644 --- a/test/tests.cc +++ b/test/tests.cc @@ -115,41 +115,6 @@ BOOST_AUTO_TEST_CASE (subtitles) libdcp::SubtitleAsset subs ("test/ref", "subs.xml"); BOOST_CHECK_EQUAL (subs.language(), "French"); -// BOOST_CHECK_EQUAL (subs.font_nodes().size(), 1); -// BOOST_CHECK_EQUAL (subs.font_nodes().front()->subtitle_nodes.size(), 4); - -#if 0 - list<shared_ptr<libdcp::SubtitleNode> >::const_iterator i = subs.font_nodes().front()->subtitle_nodes.begin (); - - BOOST_CHECK_EQUAL ((*i)->in, libdcp::Time (0, 0, 5, 198)); - BOOST_CHECK_EQUAL ((*i)->out, libdcp::Time (0, 0, 7, 115)); - BOOST_CHECK_EQUAL ((*i)->text_nodes.size(), 1); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->v_position, 15); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->text, "My jacket was Idi Amin's"); - ++i; - - BOOST_CHECK_EQUAL ((*i)->in, libdcp::Time (0, 0, 7, 177)); - BOOST_CHECK_EQUAL ((*i)->out, libdcp::Time (0, 0, 11, 31)); - BOOST_CHECK_EQUAL ((*i)->text_nodes.size(), 2); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->v_position, 21); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->text, "My corset was H.M. The Queen's"); - BOOST_CHECK_EQUAL ((*i)->text_nodes.back()->v_position, 15); - BOOST_CHECK_EQUAL ((*i)->text_nodes.back()->text, "My large wonderbra"); - ++i; - - BOOST_CHECK_EQUAL ((*i)->in, libdcp::Time (0, 0, 11, 94)); - BOOST_CHECK_EQUAL ((*i)->out, libdcp::Time (0, 0, 13, 63)); - BOOST_CHECK_EQUAL ((*i)->text_nodes.size(), 1); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->v_position, 15); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->text, "Once belonged to the Shah"); - ++i; - - BOOST_CHECK_EQUAL ((*i)->in, libdcp::Time (0, 0, 13, 104)); - BOOST_CHECK_EQUAL ((*i)->out, libdcp::Time (0, 0, 15, 177)); - BOOST_CHECK_EQUAL ((*i)->text_nodes.size(), 1); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->v_position, 15); - BOOST_CHECK_EQUAL ((*i)->text_nodes.front()->text, "And these are Roy Hattersley's jeans"); -#endif list<shared_ptr<libdcp::Subtitle> > s = subs.subtitles_at (libdcp::Time (0, 0, 6, 1)); BOOST_CHECK_EQUAL (s.size(), 1); @@ -159,6 +124,21 @@ BOOST_AUTO_TEST_CASE (subtitles) BOOST_CHECK_EQUAL (s.front()->out(), libdcp::Time (0, 0, 7, 115)); BOOST_CHECK_EQUAL (s.front()->font(), "Arial"); BOOST_CHECK_EQUAL (s.front()->size_in_pixels(1080), 53); + + s = subs.subtitles_at (libdcp::Time (0, 0, 7, 190)); + BOOST_CHECK_EQUAL (s.size(), 2); + BOOST_CHECK_EQUAL (s.front()->text(), "My corset was H.M. The Queen's"); + BOOST_CHECK_EQUAL (s.front()->v_position(), 21); + BOOST_CHECK_EQUAL (s.front()->in(), libdcp::Time (0, 0, 7, 177)); + BOOST_CHECK_EQUAL (s.front()->out(), libdcp::Time (0, 0, 11, 31)); + BOOST_CHECK_EQUAL (s.front()->font(), "Arial"); + BOOST_CHECK_EQUAL (s.front()->size_in_pixels(1080), 53); + BOOST_CHECK_EQUAL (s.back()->text(), "My large wonderbra"); + BOOST_CHECK_EQUAL (s.back()->v_position(), 15); + BOOST_CHECK_EQUAL (s.back()->in(), libdcp::Time (0, 0, 7, 177)); + BOOST_CHECK_EQUAL (s.back()->out(), libdcp::Time (0, 0, 11, 31)); + BOOST_CHECK_EQUAL (s.back()->font(), "Arial"); + BOOST_CHECK_EQUAL (s.back()->size_in_pixels(1080), 53); s = subs.subtitles_at (libdcp::Time (0, 0, 11, 95)); BOOST_CHECK_EQUAL (s.size(), 1); |
