diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-05-29 11:57:08 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-05-29 11:57:08 +0100 |
| commit | aebf2cb7812c8f593b85182611b587e6014aefc6 (patch) | |
| tree | c954ebc0cf39263b6c051e159f48e177cafae310 /src | |
| parent | 8b1958988ca234f51ec99385d81b95c1f0f092af (diff) | |
Re-work Subtitle class; remove STL text writer.
Diffstat (limited to 'src')
| -rw-r--r-- | src/dcp_reader.cc | 55 | ||||
| -rw-r--r-- | src/dcp_reader.h | 10 | ||||
| -rw-r--r-- | src/stl_binary_reader.cc | 47 | ||||
| -rw-r--r-- | src/stl_binary_writer.cc | 134 | ||||
| -rw-r--r-- | src/stl_binary_writer.h (renamed from src/convert_time.h) | 27 | ||||
| -rw-r--r-- | src/stl_text_reader.cc | 54 | ||||
| -rw-r--r-- | src/stl_text_reader.h | 6 | ||||
| -rw-r--r-- | src/stl_text_writer.cc | 84 | ||||
| -rw-r--r-- | src/stl_text_writer.h | 26 | ||||
| -rw-r--r-- | src/subtitle.cc | 76 | ||||
| -rw-r--r-- | src/subtitle.h | 90 | ||||
| -rw-r--r-- | src/time_pair.cc (renamed from src/convert_time.cc) | 35 | ||||
| -rw-r--r-- | src/wscript | 6 |
13 files changed, 380 insertions, 270 deletions
diff --git a/src/dcp_reader.cc b/src/dcp_reader.cc index 4c3384e..bd5c183 100644 --- a/src/dcp_reader.cc +++ b/src/dcp_reader.cc @@ -207,6 +207,13 @@ public: string uri; }; +struct DCPReader::ParseState { + list<shared_ptr<DCPFont> > font_nodes; + list<shared_ptr<DCPText> > text_nodes; + list<shared_ptr<DCPSubtitle> > subtitle_nodes; + boost::optional<Subtitle> subtitle; +}; + } /** @param s A string. @@ -263,6 +270,10 @@ DCPReader::DCPReader (istream& in) ParseState parse_state; examine_font_nodes (xml, font_nodes, parse_state); + if (parse_state.subtitle && !parse_state.subtitle.get().blocks.empty ()) { + _subs.push_back (parse_state.subtitle.get ()); + } + _subs.sort (); } @@ -308,7 +319,7 @@ DCPReader::examine_text_nodes ( } void -DCPReader::maybe_add_subtitle (string text, ParseState const & parse_state) +DCPReader::maybe_add_subtitle (string text, ParseState& parse_state) { if (empty_or_white_space (text)) { return; @@ -325,19 +336,31 @@ DCPReader::maybe_add_subtitle (string text, ParseState const & parse_state) DCPText effective_text (*parse_state.text_nodes.back ()); DCPSubtitle effective_subtitle (*parse_state.subtitle_nodes.back ()); - Subtitle s; - s.text = text; - s.font = font_id_to_name (effective_font.id); - s.font_size.proportional = float (effective_font.size) / (72 * 11); - s.vertical_position.proportional = float (effective_text.v_position) / 100; - s.vertical_position.reference = effective_text.v_align; - s.effect = effective_font.effect; - s.effect_colour = effective_font.effect_colour; - s.colour = effective_font.colour.get (); - s.italic = effective_font.italic.get (); - s.from.metric = effective_subtitle.in; - s.to.metric = effective_subtitle.out; - s.fade_up = effective_subtitle.fade_up_time; - s.fade_down = effective_subtitle.fade_down_time; - _subs.push_back (s); + Subtitle proposed_subtitle; + proposed_subtitle.vertical_position.proportional = float (effective_text.v_position) / 100; + proposed_subtitle.vertical_position.reference = effective_text.v_align; + proposed_subtitle.from.set_metric (effective_subtitle.in); + proposed_subtitle.to.set_metric (effective_subtitle.out); + proposed_subtitle.fade_up = effective_subtitle.fade_up_time; + proposed_subtitle.fade_down = effective_subtitle.fade_down_time; + + if (!parse_state.subtitle || !parse_state.subtitle.get().same_metadata (proposed_subtitle)) { + /* We need a new Subtitle */ + if (parse_state.subtitle && !parse_state.subtitle.get().blocks.empty ()) { + /* Push the old one */ + _subs.push_back (parse_state.subtitle.get ()); + } + parse_state.subtitle = proposed_subtitle; + } + + Block block; + block.text = text; + block.font = font_id_to_name (effective_font.id); + block.font_size.set_proportional (float (effective_font.size) / (72 * 11)); + block.effect = effective_font.effect; + block.effect_colour = effective_font.effect_colour; + block.colour = effective_font.colour.get (); + block.italic = effective_font.italic.get (); + + parse_state.subtitle.get().blocks.push_back (block); } diff --git a/src/dcp_reader.h b/src/dcp_reader.h index 51ada1a..aa8df7f 100644 --- a/src/dcp_reader.h +++ b/src/dcp_reader.h @@ -37,14 +37,10 @@ public: DCPReader (std::istream &); private: - - struct ParseState { - std::list<boost::shared_ptr<DCPFont> > font_nodes; - std::list<boost::shared_ptr<DCPText> > text_nodes; - std::list<boost::shared_ptr<DCPSubtitle> > subtitle_nodes; - }; - void maybe_add_subtitle (std::string text, ParseState const & parse_state); + struct ParseState; + + void maybe_add_subtitle (std::string text, ParseState& parse_state); void examine_font_nodes ( boost::shared_ptr<const cxml::Node> xml, diff --git a/src/stl_binary_reader.cc b/src/stl_binary_reader.cc index 0d97e2e..ebcee1b 100644 --- a/src/stl_binary_reader.cc +++ b/src/stl_binary_reader.cc @@ -26,11 +26,13 @@ #include "compose.hpp" using std::map; +using std::vector; using std::cout; using std::string; using std::istream; using boost::lexical_cast; using boost::algorithm::replace_all; +using boost::is_any_of; using boost::locale::conv::utf_to_utf; using namespace sub; @@ -120,7 +122,6 @@ STLBinaryReader::STLBinaryReader (istream& in) editor_contact_details = get_string (341, 32); for (int i = 0; i < tti_blocks; ++i) { - Subtitle sub; in.read ((char *) _buffer, 128); if (in.gcount() != 128) { @@ -131,26 +132,32 @@ STLBinaryReader::STLBinaryReader (istream& in) continue; } - sub.from.frame = get_timecode (5); - sub.to.frame = get_timecode (9); - sub.line = get_int (13, 1); - - /* XXX: justification, effects */ - - string s = get_string (16, 112); - - /* 8Ah is a new line */ - replace_all (s, "\x8a", "\n"); - - /* 8Fh is unused space, so trim the string to the first instance of that */ - size_t unused = s.find_first_of ('\x8f'); - if (unused != string::npos) { - s = s.substr (0, unused); + string const whole = get_string (16, 112); + + /* Split the text up into lines (8Ah is a new line) */ + vector<string> lines; + split (lines, whole, is_any_of ("\x8a")); + + for (size_t i = 0; i < lines.size(); ++i) { + Subtitle sub; + sub.from.set_frame (get_timecode (5)); + sub.to.set_frame (get_timecode (9)); + sub.vertical_position.line = get_int (13, 1) + i; + + /* XXX: justification, effects */ + + /* 8Fh is unused space, so trim the string to the first instance of that */ + size_t unused = lines[i].find_first_of ('\x8f'); + if (unused != string::npos) { + lines[i] = lines[i].substr (0, unused); + } + + Block block; + block.text = utf_to_utf<char> (iso6937_to_utf16 (lines[i].c_str())); + sub.blocks.push_back (block); + + _subs.push_back (sub); } - - sub.text = utf_to_utf<char> (iso6937_to_utf16 (s.c_str())); - - _subs.push_back (sub); } } diff --git a/src/stl_binary_writer.cc b/src/stl_binary_writer.cc new file mode 100644 index 0000000..34e4d73 --- /dev/null +++ b/src/stl_binary_writer.cc @@ -0,0 +1,134 @@ +/* + Copyright (C) 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 <list> +#include <cmath> +#include <fstream> +#include "stl_binary_writer.h" +#include "compose.hpp" + +using std::list; +using std::ofstream; +using std::string; +using namespace sub; + +static void +put_string (char* p, string s) +{ + memcpy (p, s.c_str (), s.length ()); +} + +static void +put_string (char* p, int n, string s) +{ + memcpy (p, s.c_str (), s.length ()); + memset (p + s.length(), ' ', s.length () - n); +} + +/** @param language ISO 3-character country code for the language of the subtitles */ +void +sub::write_stl_binary ( + list<Subtitle> subtitles, + float frames_per_second, + string language, + string original_programme_title, + string original_episode_title, + string translated_programme_title, + string translated_episode_title, + string translator_name, + string translator_contact_details, + string creation_date, + string revision_date, + int revision_number, + string country_of_origin, + string publisher, + string editor_name, + string editor_contact_details, + boost::filesystem::path file_name + ) +{ + assert (language.size() == 3); + assert (original_programme_title.size() <= 32); + assert (original_episode_title.size() <= 32); + assert (translated_programme_title.size() <= 32); + assert (translated_episode_title.size() <= 32); + assert (translator_name.size() <= 32); + assert (translator_contact_details.size() <= 32); + assert (creation_date.size() == 6); + assert (revision_date.size() == 6); + assert (revision_number <= 99); + assert (country_of_origin.size() == 3); + assert (publisher.size() <= 32); + assert (editor_name.size() <= 32); + assert (editor_contact_details.size() <= 32); + + char* buffer = new char[1024]; + ofstream output (file_name.string().c_str ()); + + /* Code page: 850 */ + put_string (buffer + 0, "850"); + /* Disk format code */ + put_string (buffer + 3, String::compose ("STL%1.01", rint (frames_per_second))); + /* Display standard code: open subtitling */ + put_string (buffer + 11, "0"); + /* Character code table: Latin (ISO 6937) */ + put_string (buffer + 12, "00"); + put_string (buffer + 14, language); + put_string (buffer + 16, 32, original_programme_title); + put_string (buffer + 48, 32, original_episode_title); + put_string (buffer + 80, 32, translated_programme_title); + put_string (buffer + 112, 32, translated_episode_title); + put_string (buffer + 144, 32, translator_name); + put_string (buffer + 176, 32, translator_contact_details); + /* Subtitle list reference code */ + put_string (buffer + 208, "0000000000000000"); + put_string (buffer + 224, creation_date); + put_string (buffer + 230, revision_date); + put_string (buffer + 236, String::compose ("%02d", revision_number)); + /* TTI blocks */ + put_string (buffer + 238, String::compose ("%05d", subtitles.size ())); + /* Total number of subtitles */ + put_string (buffer + 243, String::compose ("%05d", subtitles.size ())); + /* Total number of subtitle groups */ + put_string (buffer + 248, "000"); + /* Maximum number of displayable characters in any text row */ + /* XXX */ + put_string (buffer + 251, "99"); + /* Maximum number of displayable rows */ + /* XXX */ + put_string (buffer + 253, "99"); + /* Time code status */ + put_string (buffer + 255, "1"); + /* Start-of-programme time code */ + put_string (buffer + 256, "00000000"); + /* First-in-cue time code */ + put_string (buffer + 264, "00000000"); + /* Total number of disks */ + put_string (buffer + 272, "1"); + /* Disk sequence number */ + put_string (buffer + 273, "1"); + put_string (buffer + 274, country_of_origin); + put_string (buffer + 277, publisher); + put_string (buffer + 309, editor_name); + put_string (buffer + 341, editor_contact_details); + + output.write (buffer, 1024); + + delete[] buffer; +} diff --git a/src/convert_time.h b/src/stl_binary_writer.h index 92ec737..7dbf5a5 100644 --- a/src/convert_time.h +++ b/src/stl_binary_writer.h @@ -17,12 +17,31 @@ */ -#include "metric_time.h" -#include "frame_time.h" +#include <string> +#include <boost/filesystem.hpp> namespace sub { -FrameTime metric_to_frame (MetricTime, float frames_per_second); -MetricTime frame_to_metric (FrameTime, float frames_per_second); +class Subtitle; + +extern void write_stl_binary ( + std::list<Subtitle> subtitles, + float frames_per_second, + std::string language, + std::string original_programme_title, + std::string original_episode_title, + std::string translated_programme_title, + std::string translated_episode_title, + std::string translator_name, + std::string translator_contact_details, + std::string creation_date, + std::string revision_date, + int revision_number, + std::string country_of_origin, + std::string publisher, + std::string editor_name, + std::string editor_contact_details, + boost::filesystem::path file_name + ); } diff --git a/src/stl_text_reader.cc b/src/stl_text_reader.cc index f9e9b65..0b4141c 100644 --- a/src/stl_text_reader.cc +++ b/src/stl_text_reader.cc @@ -38,6 +38,8 @@ using namespace sub; STLTextReader::STLTextReader (istream& in) { + _subtitle.vertical_position.line = 0; + while (in.good ()) { string line; getline (in, line); @@ -91,38 +93,37 @@ STLTextReader::STLTextReader (istream& in) continue; } - _current.from.frame = from.get (); - _current.to.frame = to.get (); + _subtitle.from.set_frame (from.get ()); + _subtitle.to.set_frame (to.get ()); /* Parse ^B/^I/^U */ string text = line.substr (divider[1] + 1); for (size_t i = 0; i < text.length(); ++i) { if (text[i] == '|') { - maybe_push (); - _current.line++; + maybe_push_subtitle (); + _subtitle.vertical_position.line = _subtitle.vertical_position.line.get() + 1; } else if (text[i] == '^') { - maybe_push (); + maybe_push_block (); if ((i + 1) < text.length()) { switch (text[i + 1]) { case 'B': - _current.bold = !_current.bold; + _block.bold = !_block.bold; break; case 'I': - _current.italic = !_current.italic; + _block.italic = !_block.italic; break; case 'U': - _current.underline = !_current.underline; + _block.underline = !_block.underline; break; } } ++i; } else { - _current.text += text[i]; + _block.text += text[i]; } } - maybe_push (); - _current.line = 0; + maybe_push_subtitle (); } } } @@ -144,24 +145,37 @@ void STLTextReader::set (string name, string value) { if (name == "$FontName") { - _current.font = value; + _block.font = value; } else if (name == "$Bold") { - _current.bold = value == "True"; + _block.bold = value == "True"; } else if (name == "$Italic") { - _current.italic = value == "True"; + _block.italic = value == "True"; } else if (name == "$Underlined") { - _current.underline = value == "True"; + _block.underline = value == "True"; } else if (name == "$FontSize") { - _current.font_size.points = lexical_cast<int> (value); + _block.font_size.set_points (lexical_cast<int> (value)); + } +} + +void +STLTextReader::maybe_push_subtitle () +{ + maybe_push_block (); + + if (!_subtitle.blocks.empty ()) { + _subs.push_back (_subtitle); + _subtitle.blocks.clear (); + _subtitle.vertical_position.line = 0; } } void -STLTextReader::maybe_push () +STLTextReader::maybe_push_block () { - if (!_current.text.empty ()) { - _subs.push_back (_current); - _current.text.clear (); + if (!_block.text.empty ()) { + _subtitle.blocks.push_back (_block); + _block.text.clear (); } } + diff --git a/src/stl_text_reader.h b/src/stl_text_reader.h index c48a8e5..e6a550a 100644 --- a/src/stl_text_reader.h +++ b/src/stl_text_reader.h @@ -29,10 +29,12 @@ public: private: void set (std::string name, std::string value); - void maybe_push (); + void maybe_push_subtitle (); + void maybe_push_block (); boost::optional<FrameTime> time (std::string t) const; - Subtitle _current; + Subtitle _subtitle; + Block _block; }; } diff --git a/src/stl_text_writer.cc b/src/stl_text_writer.cc deleted file mode 100644 index 6a8601d..0000000 --- a/src/stl_text_writer.cc +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (C) 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 "stl_text_writer.h" -#include <boost/optional.hpp> - -using std::list; -using std::ostream; -using std::string; -using boost::optional; -using namespace sub; - -void -sub::write_stl_text (list<Subtitle> subtitles, int screen_height_in_points, float frames_per_second, ostream& out) -{ - optional<string> font; - optional<int> font_size; - bool bold = false; - bool italic = false; - bool underline = false; - int line = 0; - optional<FrameTime> from; - optional<FrameTime> to; - - for (list<Subtitle>::const_iterator i = subtitles.begin(); i != subtitles.end(); ++i) { - bool started_new = false; - if (!font || font.get() != i->font) { - out << "\n$FontName = " << i->font; - font = i->font; - started_new = true; - } - if (!font_size || font_size.get() != i->font_size_points (screen_height_in_points)) { - out << "\n$FontSize = " << i->font_size_points (screen_height_in_points); - font_size = i->font_size_points (screen_height_in_points); - started_new = true; - } - string text; - if (bold != i->bold) { - text += "^B"; - bold = i->bold; - } - if (italic != i->italic) { - text += "^I"; - italic = i->italic; - } - if (underline != i->underline) { - text += "^U"; - underline = i->underline; - } - - text += i->text; - - if (from && from.get() == i->from_frame(frames_per_second) && to && to.get() == i->to_frame(frames_per_second) && !started_new) { - for (int j = line; j < i->line; ++j) { - out << "|"; - } - out << text; - line = i->line; - } else { - out << "\n" << i->from_frame(frames_per_second).timecode() << "," << i->to_frame(frames_per_second).timecode() << "," << text; - from = i->from_frame (frames_per_second); - to = i->to_frame (frames_per_second); - line = 0; - } - } - - out << "\n"; -} diff --git a/src/stl_text_writer.h b/src/stl_text_writer.h deleted file mode 100644 index d44696f..0000000 --- a/src/stl_text_writer.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - Copyright (C) 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.h" - -namespace sub { - -extern void write_stl_text (std::list<Subtitle> subtitles, int screen_height_in_points, float frames_per_second, std::ostream &); - -} diff --git a/src/subtitle.cc b/src/subtitle.cc index 6d3360f..5eb5784 100644 --- a/src/subtitle.cc +++ b/src/subtitle.cc @@ -18,81 +18,65 @@ */ #include "subtitle.h" -#include "convert_time.h" -using std::list; using namespace sub; bool sub::operator< (Subtitle const & a, Subtitle const & b) { - if (a.from.frame && b.from.frame) { - return a.from.frame.get() < b.from.frame.get(); + if (a.from.frame() && b.from.frame()) { + return a.from.frame().get() < b.from.frame().get(); } - if (a.from.metric && b.from.metric) { - return a.from.metric.get() < b.from.metric.get(); + if (a.from.metric() && b.from.metric()) { + return a.from.metric().get() < b.from.metric().get(); } assert (false); } -FrameTime -Subtitle::from_frame (float frames_per_second) const -{ - if (from.frame) { - return from.frame.get (); - } - - return metric_to_frame (from.metric.get(), frames_per_second); -} -FrameTime -Subtitle::to_frame (float frames_per_second) const +float +Block::FontSize::proportional (int screen_height_in_points) const { - if (to.frame) { - return to.frame.get (); + if (_proportional) { + return _proportional.get (); } - return metric_to_frame (to.metric.get(), frames_per_second); + return float (_points.get ()) / screen_height_in_points; } -MetricTime -Subtitle::from_metric (float frames_per_second) const +int +Block::FontSize::points (int screen_height_in_points) const { - if (from.metric) { - return from.metric.get (); + if (_points) { + return _points.get (); } - return frame_to_metric (from.frame.get(), frames_per_second); + return _proportional.get() * screen_height_in_points; } -MetricTime -Subtitle::to_metric (float frames_per_second) const +bool +Subtitle::same_metadata (Subtitle const & other) const { - if (to.metric) { - return to.metric.get (); - } - - return frame_to_metric (to.frame.get(), frames_per_second); + return ( + vertical_position == other.vertical_position && + from == other.from && + to == other.to && + fade_up == other.fade_up && + fade_down == other.fade_down + ); } -float -Subtitle::font_size_proportional (int screen_height_in_points) const +bool +Subtitle::VerticalPosition::operator== (Subtitle::VerticalPosition const & other) const { - if (font_size.proportional) { - return font_size.proportional.get (); + if (proportional && reference && other.proportional && other.reference) { + return proportional.get() == other.proportional.get() && reference.get() == other.reference.get(); + } else if (line && other.line) { + return line.get() == other.line.get(); } - return float (font_size.points.get ()) / screen_height_in_points; + return false; } -int -Subtitle::font_size_points (int screen_height_in_points) const -{ - if (font_size.points) { - return font_size.points.get (); - } - - return font_size.proportional.get() * screen_height_in_points; -} diff --git a/src/subtitle.h b/src/subtitle.h index fc08ac7..ca73b4b 100644 --- a/src/subtitle.h +++ b/src/subtitle.h @@ -25,46 +25,58 @@ #include "colour.h" #include "vertical_reference.h" #include "effect.h" +#include "time_pair.h" #include <boost/optional.hpp> #include <string> #include <list> namespace sub { -class Subtitle +/** A piece of text with a single font, style, size etc. */ +class Block { public: - Subtitle () + Block () : colour (1, 1, 1) , bold (false) , italic (false) , underline (false) - , line (0) {} - + /** Subtitle text in UTF-8 */ std::string text; std::string font; /** font size */ - struct { + class FontSize { + public: + void set_proportional (float p) { + _proportional = p; + } + + void set_points (int p) { + _points = p; + } + + boost::optional<float> proportional () const { + return _proportional; + } + + boost::optional<int> points () const { + return _points; + } + + float proportional (int screen_height_in_points) const; + int points (int screen_height_in_points) const; + + private: /** as a proportion of screen height */ - boost::optional<float> proportional; + boost::optional<float> _proportional; /** in points */ - boost::optional<int> points; + boost::optional<int> _points; + } font_size; - float font_size_proportional (int screen_height_in_points) const; - int font_size_points (int screen_height_in_points) const; - - /** vertical position of the baseline of the text */ - struct { - /** as a proportion of screen height offset from some reference point */ - boost::optional<float> proportional; - /** reference position for proportional */ - boost::optional<VerticalReference> reference; - } vertical_position; - boost::optional<Effect> effect; boost::optional<Colour> effect_colour; @@ -72,28 +84,40 @@ public: bool bold; ///< true to use a bold version of font bool italic; ///< true to use an italic version of font bool underline; ///< true to underline - int line; ///< line number, starting from 0 +}; - /** from time */ - struct { - boost::optional<FrameTime> frame; - boost::optional<MetricTime> metric; - } from; +/** A line of text which starts and stops at specific times */ +class Subtitle +{ +public: + Subtitle () + {} - FrameTime from_frame (float frames_per_second) const; - MetricTime from_metric (float frames_per_second) const; + /** vertical position of the baseline of the text */ + struct VerticalPosition { - /** to time */ - struct { - boost::optional<FrameTime> frame; - boost::optional<MetricTime> metric; - } to; + /** as a proportion of screen height offset from some reference point */ + boost::optional<float> proportional; + /** reference position for proportional */ + boost::optional<VerticalReference> reference; + /** line number from the top of the screen */ + boost::optional<int> line; + + bool operator== (VerticalPosition const & other) const; + + } vertical_position; - FrameTime to_frame (float frames_per_second) const; - MetricTime to_metric (float frames_per_second) const; + /** from time */ + TimePair from; + /** to time */ + TimePair to; boost::optional<MetricTime> fade_up; boost::optional<MetricTime> fade_down; + + std::list<Block> blocks; + + bool same_metadata (Subtitle const &) const; }; bool operator< (Subtitle const & a, Subtitle const & b); diff --git a/src/convert_time.cc b/src/time_pair.cc index 3ae165b..186d54c 100644 --- a/src/convert_time.cc +++ b/src/time_pair.cc @@ -17,21 +17,40 @@ */ -#include "metric_time.h" -#include "frame_time.h" -#include "convert_time.h" +#include "time_pair.h" -using std::cout; using namespace sub; FrameTime -sub::metric_to_frame (MetricTime t, float frames_per_second) +TimePair::frame (float frames_per_second) const { - return FrameTime (t.hours(), t.minutes(), t.seconds(), t.milliseconds() * frames_per_second / 1000); + if (_frame) { + return _frame.get (); + } + + MetricTime const m = _metric.get (); + return FrameTime (m.hours(), m.minutes(), m.seconds(), m.milliseconds() * frames_per_second / 1000); } MetricTime -sub::frame_to_metric (FrameTime t, float frames_per_second) +TimePair::metric (float frames_per_second) const +{ + if (_metric) { + return _metric.get (); + } + + FrameTime const f = _frame.get (); + return MetricTime (f.hours(), f.minutes(), f.seconds(), f.frames() * 1000 / frames_per_second); +} + +bool +TimePair::operator== (TimePair const & other) const { - return MetricTime (t.hours(), t.minutes(), t.seconds(), t.frames() * 1000 / frames_per_second); + if (_metric && other._metric) { + return _metric.get() == other._metric.get(); + } else if (_frame && other._frame) { + return _frame.get() == other._frame.get(); + } + + return false; } diff --git a/src/wscript b/src/wscript index c2bdd64..dd04aa9 100644 --- a/src/wscript +++ b/src/wscript @@ -12,7 +12,6 @@ def build(bld): obj.export_includes = ['.'] obj.source = """ colour.cc - convert_time.cc dcp_reader.cc effect.cc frame_time.cc @@ -23,22 +22,21 @@ def build(bld): reader_factory.cc stl_binary_reader.cc stl_text_reader.cc - stl_text_writer.cc + time_pair.cc subtitle.cc vertical_reference.cc """ headers = """ colour.h - convert_time.h dcp_reader.h effect.h frame_time.h metric_time.h reader.h stl_text_reader.h - stl_text_writer.h subtitle.h + time_pair.h vertical_reference.h """ |
