From f902811342bb9f72bb11e2658aea14cfe8b04c64 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 21 Aug 2012 16:00:16 +0100 Subject: Recursively scan font tags in subtitles. --- src/subtitle_asset.cc | 81 ++++++++++++++++++++++++++++++++++++++------------- src/subtitle_asset.h | 7 ++++- src/xml.cc | 11 +++++++ src/xml.h | 1 + 4 files changed, 79 insertions(+), 21 deletions(-) (limited to 'src') 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 > font_nodes = sub_nodes ("Font"); - list > load_font_nodes = sub_nodes ("LoadFont"); + _load_font_nodes = sub_nodes ("LoadFont"); /* Now make Subtitle objects to represent the raw XML nodes in a sane way. */ + list > current_font_nodes; for (list >::iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) { - for (list >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) { - for (list >::iterator k = (*j)->text_nodes.begin(); k != (*j)->text_nodes.end(); ++k) { - _subtitles.push_back ( - shared_ptr ( - 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 font_node, list >& current_font_nodes) +{ + current_font_nodes.push_back (font_node); + + for (list >::iterator j = font_node->subtitle_nodes.begin(); j != font_node->subtitle_nodes.end(); ++j) { + for (list >::iterator k = (*j)->text_nodes.begin(); k != (*j)->text_nodes.end(); ++k) { + _subtitles.push_back ( + shared_ptr ( + 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 >::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 > const & font_nodes) const +{ + for (list >::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 > const & font_nodes) const +{ + for (list >::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 ("Subtitle"); + font_nodes = sub_nodes ("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 > const & load_font_nodes) const +SubtitleAsset::font_id_to_name (string id) const { - list >::const_iterator i = load_font_nodes.begin(); - while (i != load_font_nodes.end() && (*i)->id != id) { + list >::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 > subtitle_nodes; + std::list > font_nodes; }; class LoadFontNode : public XMLNode @@ -128,12 +129,16 @@ public: std::list > subtitles_at (Time t) const; private: - std::string font_id_to_name (std::string id, std::list > const & load_font_nodes) const; + std::string font_id_to_name (std::string id) const; + void examine_font_node (boost::shared_ptr font_node, std::list >& current_font_nodes); + std::string id_from_font_nodes (std::list > const & font_nodes) const; + int size_from_font_nodes (std::list > const & font_nodes) const; std::string _subtitle_id; std::string _movie_title; int64_t _reel_number; std::string _language; + std::list > _load_font_nodes; std::list > _subtitles; }; diff --git a/src/xml.cc b/src/xml.cc index 0f0d2d47..08a43ea9 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -163,6 +163,17 @@ XMLNode::int64_attribute (string name) return lexical_cast (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 (s); +} + void XMLNode::done () { diff --git a/src/xml.h b/src/xml.h index d7f6ad36..5ff5f614 100644 --- a/src/xml.h +++ b/src/xml.h @@ -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 (); -- cgit v1.2.3