Some maths operations with Time.
authorCarl Hetherington <cth@carlh.net>
Tue, 21 Aug 2012 23:11:18 +0000 (00:11 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 21 Aug 2012 23:11:18 +0000 (00:11 +0100)
src/dcp_time.cc
src/dcp_time.h
src/subtitle_asset.cc
src/subtitle_asset.h
src/xml.cc
test/tests.cc

index 0cc6b264894c00be6c11b257ddbe73084c523f17..bc15c367054ca20183b16d9673c8246013c731d4 100644 (file)
  */
 
 #include <iostream>
+#include <vector>
+#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
 #include <cmath>
 #include "dcp_time.h"
+#include "exceptions.h"
 
 using namespace std;
+using namespace boost;
 using namespace libdcp;
 
 Time::Time (int frame, int frames_per_second)
@@ -49,6 +54,20 @@ Time::Time (int frame, int frames_per_second)
        }
 }
 
+Time::Time (string time)
+{
+       vector<string> b;
+       split (b, time, is_any_of (":"));
+       if (b.size() != 4) {
+               throw DCPReadError ("unrecognised time specification");
+       }
+       
+       h = lexical_cast<int> (b[0]);
+       m = lexical_cast<int> (b[1]);
+       s = lexical_cast<int> (b[2]);
+       t = lexical_cast<int> (b[3]);
+}
+
 bool
 libdcp::operator== (Time const & a, Time const & b)
 {
@@ -77,9 +96,117 @@ libdcp::operator<= (Time const & a, Time const & b)
        return true;
 }
 
+bool
+libdcp::operator< (Time const & a, Time const & b)
+{
+       if (a.h != b.h) {
+               return a.h < b.h;
+       }
+
+       if (a.m != b.m) {
+               return a.m < b.m;
+       }
+
+       if (a.s != b.s) {
+               return a.s < b.s;
+       }
+
+       if (a.t != b.t) {
+               return a.t < b.t;
+       }
+
+       return true;
+}
+
+bool
+libdcp::operator> (Time const & a, Time const & b)
+{
+       if (a.h != b.h) {
+               return a.h > b.h;
+       }
+
+       if (a.m != b.m) {
+               return a.m > b.m;
+       }
+
+       if (a.s != b.s) {
+               return a.s > b.s;
+       }
+
+       if (a.t != b.t) {
+               return a.t > b.t;
+       }
+
+       return true;
+}
+
 ostream &
 libdcp::operator<< (ostream& s, Time const & t)
 {
        s << t.h << ":" << t.m << ":" << t.s << "." << t.t;
        return s;
 }
+
+libdcp::Time
+libdcp::operator+ (Time a, Time const & b)
+{
+       Time r;
+
+       r.t = a.t + b.t;
+       if (r.t >= 250) {
+               r.t -= 250;
+               r.s++;
+       }
+
+       r.s += a.s + b.s;
+       if (r.s >= 60) {
+               r.s -= 60;
+               r.m++;
+       }
+
+       r.m += a.m + b.m;
+       if (r.m >= 60) {
+               r.m -= 60;
+               r.h++;
+       }
+
+       r.h += a.h + b.h;
+
+       return r;
+}
+
+libdcp::Time
+libdcp::operator- (Time a, Time const & b)
+{
+       Time r;
+
+       r.t = a.t - b.t;
+       if (r.t < 0) {
+               r.t += 250;
+               r.s--;
+       }
+
+       r.s += (a.s - b.s);
+       if (r.s < 0) {
+               r.s += 60;
+               r.m--;
+       }
+
+       r.m += (a.m - b.m);
+       if (r.m < 0) {
+               r.m += 60;
+               r.h--;
+       }
+
+       r.h += (a.h - b.h);
+
+       return r;
+}
+
+float
+libdcp::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;
+       return float (at) / bt;
+}
index 626cdacae1ddb3b4f0ef18249998e6a3436a1643..0bbf55106e942546ee8094ac8ad01ca698ac4606 100644 (file)
@@ -47,6 +47,8 @@ public:
                , t (t_)
        {}
 
+       Time (std::string time);
+
        int h; ///< hours
        int m; ///< minutes
        int s; ///< seconds
@@ -55,7 +57,12 @@ public:
 
 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 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 float operator/ (Time a, Time const & b);
 
 }
 
index 9a3e3bbc9929b1302ab1d9ac8a6542a5eb5096a9..a80fdec2a0f91cafe3fbf6e75eb5c1bddfc624eb 100644 (file)
@@ -17,6 +17,7 @@
 
 */
 
+#include <boost/lexical_cast.hpp>
 #include "subtitle_asset.h"
 
 using namespace std;
@@ -68,7 +69,9 @@ SubtitleAsset::examine_font_node (shared_ptr<FontNode> font_node, list<shared_pt
                                                (*k)->v_align,
                                                (*k)->text,
                                                effective.effect.get(),
-                                               effective.effect_color.get()
+                                               effective.effect_color.get(),
+                                               (*k)->fade_up_time,
+                                               (*k)->fade_down_time
                                                )
                                        )
                                );
@@ -162,6 +165,31 @@ TextNode::TextNode (xmlpp::Node const * node)
        } else if (v == "bottom") {
                v_align = BOTTOM;
        }
+
+       fade_up_time = fade_time ("FadeUpTime");
+       fade_down_time = fade_time ("FadeUpTime");
+}
+
+
+Time
+TextNode::fade_time (string name)
+{
+       string const u = optional_string_attribute (name);
+       Time t;
+       
+       if (u.empty ()) {
+               t = Time (0, 0, 0, 20);
+       } else if (u.find (":") != string::npos) {
+               t = Time (u);
+       } else {
+               t = Time (0, 0, 0, lexical_cast<int> (u));
+       }
+
+       if (t > Time (0, 0, 8, 0)) {
+               t = Time (0, 0, 8, 0);
+       }
+
+       return t;
 }
 
 list<shared_ptr<Subtitle> >
@@ -207,7 +235,9 @@ Subtitle::Subtitle (
        VAlign v_align,
        string text,
        Effect effect,
-       Color effect_color
+       Color effect_color,
+       Time fade_up_time,
+       Time fade_down_time
        )
        : _font (font)
        , _italic (italic)
@@ -220,6 +250,8 @@ Subtitle::Subtitle (
        , _text (text)
        , _effect (effect)
        , _effect_color (effect_color)
+       , _fade_up_time (fade_up_time)
+       , _fade_down_time (fade_down_time)
 {
 
 }
index d272957edc0346e175c48198094955bda364a98c..607b054d91a3ed6ea054d611211022824df7cdb5 100644 (file)
@@ -33,6 +33,12 @@ public:
        float v_position;
        VAlign v_align;
        std::string text;
+       Time fade_up_time;
+       Time fade_down_time;
+
+private:
+       Time fade_time (std::string name);
+       
 };
 
 class SubtitleNode : public XMLNode
@@ -88,7 +94,9 @@ public:
                VAlign v_align,
                std::string text,
                Effect effect,
-               Color effect_color
+               Color effect_color,
+               Time fade_up_time,
+               Time fade_down_time
                );
 
        std::string font () const {
@@ -131,6 +139,14 @@ public:
                return _effect_color;
        }
 
+       Time fade_up_time () const {
+               return _fade_up_time;
+       }
+
+       Time fade_down_time () const {
+               return _fade_down_time;
+       }
+
        int size_in_pixels (int screen_height) const;
 
 private:
@@ -145,6 +161,8 @@ private:
        std::string _text;
        Effect _effect;
        Color _effect_color;
+       Time _fade_up_time;
+       Time _fade_down_time;
 };
 
 class SubtitleAsset : public Asset, public XMLFile
index b9ee56a889453528c2c185941d597f8e93c71ed7..35c4fe1274de2ef8e8f0e0701d6a9091f2d9b805 100644 (file)
@@ -126,13 +126,7 @@ XMLNode::ignore_node (string name)
 Time
 XMLNode::time_attribute (string name)
 {
-       string const t = string_attribute (name);
-
-       vector<string> b;
-       boost::split (b, t, is_any_of (":"));
-       assert (b.size() == 4);
-
-       return Time (lexical_cast<int> (b[0]), lexical_cast<int> (b[1]), lexical_cast<int> (b[2]), lexical_cast<int> (b[3]));
+       return Time (string_attribute (name));
 }
 
 string
index c47e8938c420cb7de005b6c7881fd8228a0942b8..2893cc6b3d8d592a548e5226b7deef05d65f0bab 100644 (file)
@@ -17,6 +17,7 @@
 
 */
 
+#include <cmath>
 #include <boost/filesystem.hpp>
 #include "KM_prng.h"
 #include "dcp.h"
@@ -191,6 +192,27 @@ BOOST_AUTO_TEST_CASE (dcp_time)
        BOOST_CHECK_EQUAL (t.s, 34);
        BOOST_CHECK_EQUAL (t.m, 18);
        BOOST_CHECK_EQUAL (t.h, 11);
+
+       libdcp::Time a (3, 2, 3, 4);
+       libdcp::Time b (2, 3, 4, 5);
+
+       libdcp::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);
+
+       a = libdcp::Time (1, 58, 56, 240);
+       b = libdcp::Time (1, 7, 12, 120);
+       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);
+
+       a = libdcp::Time (24, 12, 6, 3);
+       b = libdcp::Time (16, 8, 4, 2);
+       BOOST_CHECK_EQUAL (a / b, 1.5);
 }
 
 BOOST_AUTO_TEST_CASE (color)