From 67a414dc3826761c8933640e85560644f5f02310 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 10 Jan 2015 00:07:47 +0000 Subject: [PATCH 1/1] Fix handling of timing in SMPTE subtitles. --- TO_PORT | 1 + src/dcp_time.cc | 98 ++++++------- src/dcp_time.h | 42 +++--- src/font.cc | 21 ++- src/font.h | 7 +- src/interop_subtitle_content.cc | 16 ++- src/smpte_subtitle_content.cc | 13 +- src/subtitle.cc | 39 ++++-- src/subtitle.h | 5 +- src/text.cc | 9 +- src/text.h | 5 +- test/dcp_time_test.cc | 62 ++++++--- test/subtitle_test.cc | 239 ++++++++++++++++---------------- test/text_test.cc | 4 +- 14 files changed, 311 insertions(+), 250 deletions(-) create mode 100644 TO_PORT diff --git a/TO_PORT b/TO_PORT new file mode 100644 index 00000000..1f23b049 --- /dev/null +++ b/TO_PORT @@ -0,0 +1 @@ +SMPTE editable units stuff \ No newline at end of file diff --git a/src/dcp_time.cc b/src/dcp_time.cc index 4033e5dd..83a7f2bb 100644 --- a/src/dcp_time.cc +++ b/src/dcp_time.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -33,31 +33,23 @@ using namespace std; using namespace boost; using namespace dcp; -Time::Time (int frame, int frames_per_second) +Time::Time (int frame, int frames_per_second, int tcr_) : h (0) , m (0) , s (0) - , t (0) + , e (0) + , tcr (tcr_) { - set (double (frame) / frames_per_second); -} - -Time::Time (int64_t ticks) -{ - h = ticks / (60 * 60 * 250); - ticks -= int64_t (h) * 60 * 60 * 250; - m = ticks / (60 * 250); - ticks -= int64_t (m) * 60 * 250; - s = ticks / 250; - ticks -= int64_t (s) * 250; - t = ticks; + set (double (frame) / frames_per_second, tcr); } void -Time::set (double ss) +Time::set (double seconds, int tcr_) { - s = floor (ss); - t = int (round (1000 * (ss - s) / 4)); + s = floor (seconds); + tcr = tcr_; + + e = int (round ((seconds - s) * tcr)); if (s >= 60) { m = s / 60; @@ -70,7 +62,8 @@ Time::set (double ss) } } -Time::Time (string time) +Time::Time (string time, int tcr_) + : tcr (tcr_) { vector b; split (b, time, is_any_of (":")); @@ -81,13 +74,13 @@ Time::Time (string time) h = raw_convert (b[0]); m = raw_convert (b[1]); s = raw_convert (b[2]); - t = raw_convert (b[3]); + e = raw_convert (b[3]); } bool dcp::operator== (Time const & a, Time const & b) { - return (a.h == b.h && a.m == b.m && a.s == b.s && a.t == b.t); + return (a.h == b.h && a.m == b.m && a.s == b.s && (a.e * b.tcr) == (b.e * a.tcr)); } bool @@ -123,8 +116,8 @@ dcp::operator< (Time const & a, Time const & b) return a.s < b.s; } - if (a.t != b.t) { - return a.t < b.t; + if ((a.e * b.tcr) != (b.e * a.tcr)) { + return (a.e * b.tcr) < (b.e * a.tcr); } return true; @@ -145,8 +138,8 @@ dcp::operator> (Time const & a, Time const & b) return a.s > b.s; } - if (a.t != b.t) { - return a.t > b.t; + if ((a.e * b.tcr) != (b.e * a.tcr)) { + return (a.e * b.tcr) > (b.e * a.tcr); } return true; @@ -155,18 +148,27 @@ dcp::operator> (Time const & a, Time const & b) ostream & dcp::operator<< (ostream& s, Time const & t) { - s << t.h << ":" << t.m << ":" << t.s << "." << t.t; + s << t.h << ":" << t.m << ":" << t.s << "." << t.e; return s; } dcp::Time -dcp::operator+ (Time a, Time const & b) +dcp::operator+ (Time a, Time b) { Time r; - r.t = a.t + b.t; - if (r.t >= 250) { - r.t -= 250; + /* Make sure we have a common tcr */ + if (a.tcr != b.tcr) { + a.e *= b.tcr; + b.e *= a.tcr; + r.tcr = a.tcr * b.tcr; + } else { + r.tcr = a.tcr; + } + + r.e = a.e + b.e; + if (r.e >= r.tcr) { + r.e -= r.tcr; r.s++; } @@ -188,13 +190,22 @@ dcp::operator+ (Time a, Time const & b) } dcp::Time -dcp::operator- (Time a, Time const & b) +dcp::operator- (Time a, Time b) { Time r; - r.t = a.t - b.t; - if (r.t < 0) { - r.t += 250; + /* Make sure we have a common tcr */ + if (a.tcr != b.tcr) { + a.e *= b.tcr; + b.e *= a.tcr; + r.tcr = a.tcr * b.tcr; + } else { + r.tcr = a.tcr; + } + + r.e = a.e - b.e; + if (r.e < 0) { + r.e += r.tcr; r.s--; } @@ -218,29 +229,22 @@ dcp::operator- (Time a, Time const & b) float dcp::operator/ (Time a, Time const & b) { - int64_t const at = a.h * 3600 * 250 + a.m * 60 * 250 + a.s * 250 + a.t; - int64_t const bt = b.h * 3600 * 250 + b.m * 60 * 250 + b.s * 250 + b.t; + int64_t const at = a.h * 3600 + a.m * 60 + a.s * float (a.e) / a.tcr; + int64_t const bt = b.h * 3600 + b.m * 60 + b.s * float (b.e) / b.tcr; return float (at) / bt; } -/** @return A string of the form h:m:s:t */ +/** @return A string of the form h:m:s:e */ string Time::to_string () const { stringstream str; - str << h << ":" << m << ":" << s << ":" << t; + str << h << ":" << m << ":" << s << ":" << e; return str.str (); } -/** @return This time in ticks */ int64_t -Time::to_ticks () const -{ - return int64_t(t) + int64_t(s) * 250 + int64_t(m) * 60 * 250 + int64_t(h) * 60 * 60 * 250; -} - -double -Time::to_seconds () const +Time::to_editable_units (int tcr_) const { - return double (to_ticks ()) / 250; + return (int64_t(e) * float (tcr_ / tcr)) + int64_t(s) * tcr_ + int64_t(m) * 60 * tcr_ + int64_t(h) * 60 * 60 * tcr_; } diff --git a/src/dcp_time.h b/src/dcp_time.h index 70bc5573..23f860cf 100644 --- a/src/dcp_time.h +++ b/src/dcp_time.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -37,41 +37,41 @@ namespace dcp { class Time { public: - Time () : h (0), m (0), s (0), t (0) {} + Time () : h (0), m (0), s (0), e (0), tcr (1) {} - Time (int64_t ticks); - - /** Construct a Time from a frame index (starting from 0) - * and a frames per second count. + /** Construct a Time from a frame index (starting from 0), + * a frames per second count and a timecode rate. */ - Time (int frame, int frames_per_second); + Time (int frame, int frames_per_second, int tcr); - /** Construct a Time from hours, minutes, seconds and ticks. + /** Construct a Time from hours, minutes, seconds, editable units and a timecode rate. * @param h_ Hours. * @param m_ Minutes. * @param s_ Seconds. - * @param t_ Ticks (where 1 tick is 4 milliseconds). + * @param e_ Editable units (where 1 editable unit is 1 / tcr_ seconds) + * @param tcr_ Timecode rate; i.e. number of editable units per second. */ - Time (int h_, int m_, int s_, int t_) + Time (int h_, int m_, int s_, int e_, int tcr_) : h (h_) , m (m_) , s (s_) - , t (t_) + , e (e_) + , tcr (tcr_) {} - Time (std::string time); + Time (std::string time, int tcr); - int h; ///< hours - int m; ///< minutes - int s; ///< seconds - int t; ///< `ticks', where 1 tick is 4 milliseconds + int h; ///< hours + int m; ///< minutes + int s; ///< seconds + int e; ///< editable units (where 1 editable unit is 1 / tcr_ seconds) + int tcr; ///< timecode rate: the number of editable units per second. std::string to_string () const; - int64_t to_ticks () const; - double to_seconds () const; + int64_t to_editable_units (int tcr_) const; private: - void set (double); + void set (double seconds, int tcr); }; extern bool operator== (Time const & a, Time const & b); @@ -81,8 +81,8 @@ extern bool operator< (Time const & a, Time const & b); extern bool operator> (Time const & a, Time const & b); extern bool operator>= (Time const & a, Time const & b); extern std::ostream & operator<< (std::ostream & s, Time const & t); -extern Time operator+ (Time a, Time const & b); -extern Time operator- (Time a, Time const & b); +extern Time operator+ (Time a, Time b); +extern Time operator- (Time a, Time b); extern float operator/ (Time a, Time const & b); } diff --git a/src/font.cc b/src/font.cc index 99f49f90..8656e909 100644 --- a/src/font.cc +++ b/src/font.cc @@ -23,6 +23,7 @@ #include "xml.h" #include "text.h" #include +#include using std::string; using std::list; @@ -30,7 +31,7 @@ using boost::shared_ptr; using boost::optional; using namespace dcp; -Font::Font (boost::shared_ptr node) +Font::Font (cxml::ConstNodePtr node, int tcr) { text = node->content (); @@ -49,9 +50,21 @@ Font::Font (boost::shared_ptr node) if (c) { effect_colour = Colour (c.get ()); } - subtitle_nodes = type_children (node, "Subtitle"); - font_nodes = type_children (node, "Font"); - text_nodes = type_children (node, "Text"); + + list s = node->node_children ("Subtitle"); + BOOST_FOREACH (cxml::NodePtr& i, s) { + subtitle_nodes.push_back (shared_ptr (new Subtitle (i, tcr))); + } + + list f = node->node_children ("Font"); + BOOST_FOREACH (cxml::NodePtr& i, f) { + font_nodes.push_back (shared_ptr (new Font (i, tcr))); + } + + list t = node->node_children ("Text"); + BOOST_FOREACH (cxml::NodePtr& i, t) { + text_nodes.push_back (shared_ptr (new Text (i, tcr))); + } } Font::Font (std::list > const & font_nodes) diff --git a/src/font.h b/src/font.h index d5ea5636..a2589be4 100644 --- a/src/font.h +++ b/src/font.h @@ -23,14 +23,11 @@ #include "types.h" #include "subtitle.h" +#include #include #include #include -namespace cxml { - class Node; -} - namespace dcp { /** @class Font @@ -43,7 +40,7 @@ public: : size (0) {} - Font (boost::shared_ptr node); + Font (cxml::ConstNodePtr node, int tcr); Font (std::list > const & font_nodes); std::string text; diff --git a/src/interop_subtitle_content.cc b/src/interop_subtitle_content.cc index 218dbaea..1b6ee1a9 100644 --- a/src/interop_subtitle_content.cc +++ b/src/interop_subtitle_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -22,9 +22,11 @@ #include "xml.h" #include "raw_convert.h" #include "font.h" +#include using std::list; using std::string; +using std::cout; using boost::shared_ptr; using boost::optional; using boost::dynamic_pointer_cast; @@ -38,9 +40,13 @@ InteropSubtitleContent::InteropSubtitleContent (boost::filesystem::path file) _id = xml->string_child ("SubtitleID"); _movie_title = xml->string_child ("MovieTitle"); - _load_font_nodes = type_children (xml, "LoadFont"); - list > font_nodes = type_children (xml, "Font"); + + list f = xml->node_children ("Font"); + list > font_nodes; + BOOST_FOREACH (cxml::NodePtr& i, f) { + font_nodes.push_back (shared_ptr (new Font (i, 250))); + } parse_common (xml, font_nodes); } @@ -148,8 +154,8 @@ InteropSubtitleContent::xml_as_string () const subtitle_element->set_attribute ("SpotNumber", raw_convert (spot_number++)); subtitle_element->set_attribute ("TimeIn", i->in().to_string()); subtitle_element->set_attribute ("TimeOut", i->out().to_string()); - subtitle_element->set_attribute ("FadeUpTime", raw_convert (i->fade_up_time().to_ticks())); - subtitle_element->set_attribute ("FadeDownTime", raw_convert (i->fade_down_time().to_ticks())); + subtitle_element->set_attribute ("FadeUpTime", raw_convert (i->fade_up_time().to_editable_units(250))); + subtitle_element->set_attribute ("FadeDownTime", raw_convert (i->fade_down_time().to_editable_units(250))); last_in = i->in (); last_out = i->out (); diff --git a/src/smpte_subtitle_content.cc b/src/smpte_subtitle_content.cc index e54b33c3..910219cb 100644 --- a/src/smpte_subtitle_content.cc +++ b/src/smpte_subtitle_content.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -24,10 +24,12 @@ #include "xml.h" #include "AS_DCP.h" #include "KM_util.h" +#include using std::string; using std::list; using std::stringstream; +using std::cout; using boost::shared_ptr; using namespace dcp; @@ -62,8 +64,15 @@ SMPTESubtitleContent::SMPTESubtitleContent (boost::filesystem::path file, bool m _load_font_nodes = type_children (xml, "LoadFont"); + int tcr = xml->number_child ("TimeCodeRate"); + shared_ptr subtitle_list = xml->optional_node_child ("SubtitleList"); - list > font_nodes = type_children (subtitle_list, "Font"); + + list f = subtitle_list->node_children ("Font"); + list > font_nodes; + BOOST_FOREACH (cxml::NodePtr& i, f) { + font_nodes.push_back (shared_ptr (new Font (i, tcr))); + } parse_common (xml, font_nodes); } diff --git a/src/subtitle.cc b/src/subtitle.cc index 12714961..6c2ccd7e 100644 --- a/src/subtitle.cc +++ b/src/subtitle.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -25,36 +25,47 @@ #include using std::string; +using std::list; +using boost::optional; using boost::shared_ptr; using boost::lexical_cast; using namespace dcp; -Subtitle::Subtitle (boost::shared_ptr node) +Subtitle::Subtitle (boost::shared_ptr node, int tcr) { - in = Time (node->string_attribute ("TimeIn")); - out = Time (node->string_attribute ("TimeOut")); - font_nodes = type_children (node, "Font"); - text_nodes = type_children (node, "Text"); - fade_up_time = fade_time (node, "FadeUpTime"); - fade_down_time = fade_time (node, "FadeDownTime"); + in = Time (node->string_attribute ("TimeIn"), tcr); + out = Time (node->string_attribute ("TimeOut"), tcr); + + list f = node->node_children ("Font"); + for (list::iterator i = f.begin(); i != f.end(); ++i) { + font_nodes.push_back (shared_ptr (new Font (*i, tcr))); + } + + list t = node->node_children ("Text"); + for (list::iterator i = t.begin(); i != t.end(); ++i) { + text_nodes.push_back (shared_ptr (new Text (*i, tcr))); + } + + fade_up_time = fade_time (node, "FadeUpTime", tcr); + fade_down_time = fade_time (node, "FadeDownTime", tcr); } Time -Subtitle::fade_time (shared_ptr node, string name) +Subtitle::fade_time (shared_ptr node, string name, int tcr) { string const u = node->optional_string_attribute (name).get_value_or (""); Time t; if (u.empty ()) { - t = Time (0, 0, 0, 20); + t = Time (0, 0, 0, 20, 250); } else if (u.find (":") != string::npos) { - t = Time (u); + t = Time (u, tcr); } else { - t = Time (0, 0, 0, lexical_cast (u)); + t = Time (0, 0, 0, lexical_cast (u), tcr); } - if (t > Time (0, 0, 8, 0)) { - t = Time (0, 0, 8, 0); + if (t > Time (0, 0, 8, 0, 250)) { + t = Time (0, 0, 8, 0, 250); } return t; diff --git a/src/subtitle.h b/src/subtitle.h index 073bfb0c..0958a1d4 100644 --- a/src/subtitle.h +++ b/src/subtitle.h @@ -22,6 +22,7 @@ #include "dcp_time.h" #include +#include #include namespace cxml { @@ -37,7 +38,7 @@ class Subtitle { public: Subtitle () {} - Subtitle (boost::shared_ptr node); + Subtitle (boost::shared_ptr node, int tcr); Time in; Time out; @@ -47,7 +48,7 @@ public: std::list > text_nodes; private: - Time fade_time (boost::shared_ptr, std::string name); + Time fade_time (boost::shared_ptr, std::string name, int tcr); }; } diff --git a/src/text.cc b/src/text.cc index 782d1711..a846d961 100644 --- a/src/text.cc +++ b/src/text.cc @@ -25,8 +25,10 @@ #include "xml.h" #include "font.h" #include +#include using std::string; +using std::list; using boost::shared_ptr; using boost::optional; using namespace dcp; @@ -35,7 +37,7 @@ using namespace dcp; * in this object's member variables. * @param node Node to read. */ -Text::Text (boost::shared_ptr node) +Text::Text (boost::shared_ptr node, int tcr) : v_align (CENTER) { text = node->content (); @@ -54,5 +56,8 @@ Text::Text (boost::shared_ptr node) v_align = string_to_valign (v.get ()); } - font_nodes = type_children (node, "Font"); + list f = node->node_children ("Font"); + BOOST_FOREACH (cxml::NodePtr& i, f) { + font_nodes.push_back (shared_ptr (new Font (i, tcr))); + } } diff --git a/src/text.h b/src/text.h index 268d146c..fe314f76 100644 --- a/src/text.h +++ b/src/text.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2014 Carl Hetherington + Copyright (C) 2012-2015 Carl Hetherington 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 @@ -23,6 +23,7 @@ #include "types.h" #include +#include #include namespace cxml { @@ -45,7 +46,7 @@ public: , v_align (TOP) {} - Text (boost::shared_ptr node); + Text (boost::shared_ptr node, int tcr); float v_position; VAlign v_align; diff --git a/test/dcp_time_test.cc b/test/dcp_time_test.cc index 9f0072ab..c987517e 100644 --- a/test/dcp_time_test.cc +++ b/test/dcp_time_test.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2013 Carl Hetherington + Copyright (C) 2013-2015 Carl Hetherington 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 @@ -23,53 +23,69 @@ /** Check that dcp::Time works */ BOOST_AUTO_TEST_CASE (dcp_time) { - dcp::Time t (977143, 24); + /* tcr of 250 makes the editable event length the same as an Interop `tick' */ + dcp::Time t (977143, 24, 250); - BOOST_CHECK_EQUAL (t.t, 73); + BOOST_CHECK_EQUAL (t.e, 73); BOOST_CHECK_EQUAL (t.s, 34); BOOST_CHECK_EQUAL (t.m, 18); BOOST_CHECK_EQUAL (t.h, 11); BOOST_CHECK_EQUAL (t.to_string(), "11:18:34:73"); - BOOST_CHECK_EQUAL (t.to_ticks(), 10178573); - dcp::Time a (3, 2, 3, 4); - dcp::Time b (2, 3, 4, 5); + /* Use a tcr of 24 so that the editable event is a frame */ + dcp::Time a (3, 2, 3, 4, 24); + dcp::Time b (2, 3, 4, 5, 24); dcp::Time r = a - b; BOOST_CHECK_EQUAL (r.h, 0); BOOST_CHECK_EQUAL (r.m, 58); BOOST_CHECK_EQUAL (r.s, 58); - BOOST_CHECK_EQUAL (r.t, 249); - BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:249"); - BOOST_CHECK_EQUAL (r.to_ticks(), 884749); + BOOST_CHECK_EQUAL (r.e, 23); + BOOST_CHECK_EQUAL (r.to_string(), "0:58:58:23"); - a = dcp::Time (1, 58, 56, 240); - b = dcp::Time (1, 7, 12, 120); + /* Different tcr (25) */ + a = dcp::Time (1, 58, 56, 2, 25); + b = dcp::Time (1, 7, 12, 1, 25); r = a + b; BOOST_CHECK_EQUAL (r.h, 3); BOOST_CHECK_EQUAL (r.m, 6); - BOOST_CHECK_EQUAL (r.s, 9); - BOOST_CHECK_EQUAL (r.t, 110); - BOOST_CHECK_EQUAL (r.to_string(), "3:6:9:110"); - BOOST_CHECK_EQUAL (r.to_ticks(), 2792360); + BOOST_CHECK_EQUAL (r.s, 8); + BOOST_CHECK_EQUAL (r.e, 3); + BOOST_CHECK_EQUAL (r.to_string(), "3:6:8:3"); - a = dcp::Time (24, 12, 6, 3); - b = dcp::Time (16, 8, 4, 2); + /* Another arbitrary tcr (30) */ + a = dcp::Time (24, 12, 6, 3, 30); + b = dcp::Time (16, 8, 4, 2, 30); BOOST_CHECK_CLOSE (a / b, 1.5, 1e-5); - BOOST_CHECK_EQUAL (dcp::Time (4128391203LL).to_ticks(), 4128391203LL); - BOOST_CHECK_EQUAL (dcp::Time (60000).to_ticks(), 60000); + a = dcp::Time (3600 * 24, 24, 250); + BOOST_CHECK_EQUAL (a.h, 1); + BOOST_CHECK_EQUAL (a.m, 0); + BOOST_CHECK_EQUAL (a.s, 0); + BOOST_CHECK_EQUAL (a.e, 0); + + a = dcp::Time (60 * 24, 24, 250); + BOOST_CHECK_EQUAL (a.h, 0); + BOOST_CHECK_EQUAL (a.m, 1); + BOOST_CHECK_EQUAL (a.s, 0); + BOOST_CHECK_EQUAL (a.e, 0); /* Check rounding; 3424 is 142.666666666... seconds or 0.166666666... ticks */ - a = dcp::Time (3424, 24); + a = dcp::Time (3424, 24, 250); BOOST_CHECK_EQUAL (a.h, 0); BOOST_CHECK_EQUAL (a.m, 2); BOOST_CHECK_EQUAL (a.s, 22); - BOOST_CHECK_EQUAL (a.t, 167); + BOOST_CHECK_EQUAL (a.e, 167); - a = dcp::Time (3425, 24); + a = dcp::Time (3425, 24, 250); BOOST_CHECK_EQUAL (a.h, 0); BOOST_CHECK_EQUAL (a.m, 2); BOOST_CHECK_EQUAL (a.s, 22); - BOOST_CHECK_EQUAL (a.t, 177); + BOOST_CHECK_EQUAL (a.e, 177); + + /* Check addition of times with different tcrs */ + a = dcp::Time (0, 0, 0, 3, 24); + b = dcp::Time (0, 0, 0, 4, 48); + r = a + b; + BOOST_CHECK_EQUAL (r, dcp::Time (0, 0, 0, 240, 1152)); } diff --git a/test/subtitle_test.cc b/test/subtitle_test.cc index c7137bec..a3694717 100644 --- a/test/subtitle_test.cc +++ b/test/subtitle_test.cc @@ -32,91 +32,91 @@ BOOST_AUTO_TEST_CASE (subtitles1) BOOST_CHECK_EQUAL (subs.language(), "French"); - list s = subs.subtitles_during (dcp::Time (0, 0, 6, 1), dcp::Time (0, 0, 6, 2)); - BOOST_CHECK_EQUAL (s.size(), 1); + list s = subs.subtitles_during (dcp::Time (0, 0, 6, 1, 250), dcp::Time (0, 0, 6, 2, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 1); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFontId"), false, dcp::Colour (255, 255, 255), 39, - dcp::Time (0, 0, 5, 198), - dcp::Time (0, 0, 7, 115), + dcp::Time (0, 0, 5, 198, 250), + dcp::Time (0, 0, 7, 115, 250), 15, dcp::BOTTOM, "My jacket was Idi Amin's", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 1), - dcp::Time (0, 0, 0, 1) + dcp::Time (0, 0, 0, 1, 250), + dcp::Time (0, 0, 0, 1, 250) )); - s = subs.subtitles_during (dcp::Time (0, 0, 7, 190), dcp::Time (0, 0, 7, 191)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 0, 7, 190, 250), dcp::Time (0, 0, 7, 191, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFontId"), true, dcp::Colour (255, 255, 255), 39, - dcp::Time (0, 0, 7, 177), - dcp::Time (0, 0, 11, 31), + dcp::Time (0, 0, 7, 177, 250), + dcp::Time (0, 0, 11, 31, 250), 21, dcp::BOTTOM, "My corset was H.M. The Queen's", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 1), - dcp::Time (0, 0, 0, 1) + dcp::Time (0, 0, 0, 1, 250), + dcp::Time (0, 0, 0, 1, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFontId"), false, dcp::Colour (255, 255, 255), 39, - dcp::Time (0, 0, 7, 177), - dcp::Time (0, 0, 11, 31), + dcp::Time (0, 0, 7, 177, 250), + dcp::Time (0, 0, 11, 31, 250), 15, dcp::BOTTOM, "My large wonderbra", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 1), - dcp::Time (0, 0, 0, 1) + dcp::Time (0, 0, 0, 1, 250), + dcp::Time (0, 0, 0, 1, 250) )); - s = subs.subtitles_during (dcp::Time (0, 0, 11, 95), dcp::Time (0, 0, 11, 96)); - BOOST_CHECK_EQUAL (s.size(), 1); + s = subs.subtitles_during (dcp::Time (0, 0, 11, 95, 250), dcp::Time (0, 0, 11, 96, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 1); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFontId"), false, dcp::Colour (255, 255, 255), 39, - dcp::Time (0, 0, 11, 94), - dcp::Time (0, 0, 13, 63), + dcp::Time (0, 0, 11, 94, 250), + dcp::Time (0, 0, 13, 63, 250), 15, dcp::BOTTOM, "Once belonged to the Shah", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 1), - dcp::Time (0, 0, 0, 1) + dcp::Time (0, 0, 0, 1, 250), + dcp::Time (0, 0, 0, 1, 250) )); - s = subs.subtitles_during (dcp::Time (0, 0, 14, 42), dcp::Time (0, 0, 14, 43)); - BOOST_CHECK_EQUAL (s.size(), 1); + s = subs.subtitles_during (dcp::Time (0, 0, 14, 42, 250), dcp::Time (0, 0, 14, 43, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 1); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFontId"), false, dcp::Colour (255, 255, 255), 39, - dcp::Time (0, 0, 13, 104), - dcp::Time (0, 0, 15, 177), + dcp::Time (0, 0, 13, 104, 250), + dcp::Time (0, 0, 15, 177, 250), 15, dcp::BOTTOM, "And these are Roy Hattersley's jeans", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 1), - dcp::Time (0, 0, 0, 1) + dcp::Time (0, 0, 0, 1, 250), + dcp::Time (0, 0, 0, 1, 250) )); } @@ -125,303 +125,300 @@ BOOST_AUTO_TEST_CASE (subtitles2) { dcp::InteropSubtitleContent subs ("test/data/subs2.xml"); - list s = subs.subtitles_during (dcp::Time (0, 0, 42, 100), dcp::Time (0, 0, 42, 101)); - BOOST_CHECK_EQUAL (s.size(), 2); + list s = subs.subtitles_during (dcp::Time (0, 0, 42, 100, 250), dcp::Time (0, 0, 42, 101, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 0, 41, 62), - dcp::Time (0, 0, 43, 52), + dcp::Time (0, 0, 41, 62, 250), + dcp::Time (0, 0, 43, 52, 250), 89, dcp::TOP, "At afternoon tea with John Peel", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 0, 41, 62), - dcp::Time (0, 0, 43, 52), + dcp::Time (0, 0, 41, 62, 250), + dcp::Time (0, 0, 43, 52, 250), 95, dcp::TOP, "I enquired if his accent was real", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 0, 50, 50), dcp::Time (0, 0, 50, 51)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 0, 50, 50, 250), dcp::Time (0, 0, 50, 51, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 0, 50, 42), - dcp::Time (0, 0, 52, 21), + dcp::Time (0, 0, 50, 42, 250), + dcp::Time (0, 0, 52, 21, 250), 89, dcp::TOP, "He said \"out of the house", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 0, 50, 42), - dcp::Time (0, 0, 52, 21), + dcp::Time (0, 0, 50, 42, 250), + dcp::Time (0, 0, 52, 21, 250), 95, dcp::TOP, "I'm incredibly scouse", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 2, 300), dcp::Time (0, 1, 2, 301)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 2, 300, 250), dcp::Time (0, 1, 2, 301, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 2, 208), - dcp::Time (0, 1, 4, 10), + dcp::Time (0, 1, 2, 208, 250), + dcp::Time (0, 1, 4, 10, 250), 89, dcp::TOP, "At home it depends how I feel.\"", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 2, 208), - dcp::Time (0, 1, 4, 10), + dcp::Time (0, 1, 2, 208, 250), + dcp::Time (0, 1, 4, 10, 250), 95, dcp::TOP, "I spent a long weekend in Brighton", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 15, 50), dcp::Time (0, 1, 15, 51)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 15, 50, 250), dcp::Time (0, 1, 15, 51, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 15, 42), - dcp::Time (0, 1, 16, 42), + dcp::Time (0, 1, 15, 42, 250), + dcp::Time (0, 1, 16, 42, 250), 89, dcp::TOP, "With the legendary Miss Enid Blyton", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 15, 42), - dcp::Time (0, 1, 16, 42), + dcp::Time (0, 1, 15, 42, 250), + dcp::Time (0, 1, 16, 42, 250), 95, dcp::TOP, "She said \"you be Noddy", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 27, 200), dcp::Time (0, 1, 27, 201)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 27, 200, 250), dcp::Time (0, 1, 27, 201, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 27, 115), - dcp::Time (0, 1, 28, 208), + dcp::Time (0, 1, 27, 115, 250), + dcp::Time (0, 1, 28, 208, 250), 89, dcp::TOP, "That curious creature the Sphinx", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 27, 115), - dcp::Time (0, 1, 28, 208), + dcp::Time (0, 1, 27, 115, 250), + dcp::Time (0, 1, 28, 208, 250), 95, dcp::TOP, "Is smarter than anyone thinks", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 42, 300), dcp::Time (0, 1, 42, 301)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 42, 300, 250), dcp::Time (0, 1, 42, 301, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 42, 229), - dcp::Time (0, 1, 45, 62), + dcp::Time (0, 1, 42, 229, 250), + dcp::Time (0, 1, 45, 62, 250), 89, dcp::TOP, "It sits there and smirks", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 42, 229), - dcp::Time (0, 1, 45, 62), + dcp::Time (0, 1, 42, 229, 250), + dcp::Time (0, 1, 45, 62, 250), 95, dcp::TOP, "And you don't think it works", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 45, 200), dcp::Time (0, 1, 45, 201)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 45, 200, 250), dcp::Time (0, 1, 45, 201, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 45, 146), - dcp::Time (0, 1, 47, 94), + dcp::Time (0, 1, 45, 146, 250), + dcp::Time (0, 1, 47, 94, 250), 89, dcp::TOP, "Then when you're not looking, it winks.", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 45, 146), - dcp::Time (0, 1, 47, 94), + dcp::Time (0, 1, 45, 146, 250), + dcp::Time (0, 1, 47, 94, 250), 95, dcp::TOP, "When it snows you will find Sister Sledge", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 1, 47, 249), dcp::Time (0, 1, 47, 250)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 1, 47, 249, 250), dcp::Time (0, 1, 47, 250, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 47, 146), - dcp::Time (0, 1, 48, 167), + dcp::Time (0, 1, 47, 146, 250), + dcp::Time (0, 1, 48, 167, 250), 89, dcp::TOP, "Out mooning, at night, on the ledge", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), false, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 1, 47, 146), - dcp::Time (0, 1, 48, 167), + dcp::Time (0, 1, 47, 146, 250), + dcp::Time (0, 1, 48, 167, 250), 95, dcp::TOP, "One storey down", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - s = subs.subtitles_during (dcp::Time (0, 2, 6, 210), dcp::Time (0, 2, 6, 211)); - BOOST_CHECK_EQUAL (s.size(), 2); + s = subs.subtitles_during (dcp::Time (0, 2, 6, 210, 250), dcp::Time (0, 2, 6, 211, 250)); + BOOST_REQUIRE_EQUAL (s.size(), 2); BOOST_CHECK_EQUAL (s.front(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 2, 5, 208), - dcp::Time (0, 2, 7, 31), + dcp::Time (0, 2, 5, 208, 250), + dcp::Time (0, 2, 7, 31, 250), 89, dcp::TOP, "HELLO", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); BOOST_CHECK_EQUAL (s.back(), dcp::SubtitleString ( string ("theFont"), true, dcp::Colour (255, 255, 255), 42, - dcp::Time (0, 2, 5, 208), - dcp::Time (0, 2, 7, 31), + dcp::Time (0, 2, 5, 208, 250), + dcp::Time (0, 2, 7, 31, 250), 95, dcp::TOP, "WORLD", dcp::BORDER, dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0), - dcp::Time (0, 0, 0, 0) + dcp::Time (0, 0, 0, 0, 250), + dcp::Time (0, 0, 0, 0, 250) )); - - - } diff --git a/test/text_test.cc b/test/text_test.cc index 55cb20c1..b8d76207 100644 --- a/test/text_test.cc +++ b/test/text_test.cc @@ -31,7 +31,7 @@ BOOST_AUTO_TEST_CASE (text_test1) text->set_attribute("VAlign", "top"); text->add_child_text("Hello world"); - dcp::Text t (cxml::NodePtr (new cxml::Node (text))); + dcp::Text t (cxml::NodePtr (new cxml::Node (text)), 250); BOOST_CHECK_CLOSE (t.v_position, 4.2, 0.001); BOOST_CHECK_EQUAL (t.v_align, dcp::TOP); BOOST_CHECK_EQUAL (t.text, "Hello world"); @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE (text_test2) text->set_attribute("Valign", "top"); text->add_child_text("Hello world"); - dcp::Text t (cxml::NodePtr (new cxml::Node (text))); + dcp::Text t (cxml::NodePtr (new cxml::Node (text)), 250); BOOST_CHECK_CLOSE (t.v_position, 4.2, 0.001); BOOST_CHECK_EQUAL (t.v_align, dcp::TOP); BOOST_CHECK_EQUAL (t.text, "Hello world"); -- 2.30.2