summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2012-08-22 00:11:18 +0100
committerCarl Hetherington <cth@carlh.net>2012-08-22 00:11:18 +0100
commit9b84debc374f426bb3a00baa82bae5fdd88a018e (patch)
tree71cc6972a48f469cd83dc0b0ee60953645390fd4
parentdf6ed597b720399f02e7b75a7cf448d0956c89a1 (diff)
Some maths operations with Time.
-rw-r--r--src/dcp_time.cc127
-rw-r--r--src/dcp_time.h7
-rw-r--r--src/subtitle_asset.cc36
-rw-r--r--src/subtitle_asset.h20
-rw-r--r--src/xml.cc8
-rw-r--r--test/tests.cc22
6 files changed, 210 insertions, 10 deletions
diff --git a/src/dcp_time.cc b/src/dcp_time.cc
index 0cc6b264..bc15c367 100644
--- a/src/dcp_time.cc
+++ b/src/dcp_time.cc
@@ -22,10 +22,15 @@
*/
#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;
+}
diff --git a/src/dcp_time.h b/src/dcp_time.h
index 626cdaca..0bbf5510 100644
--- a/src/dcp_time.h
+++ b/src/dcp_time.h
@@ -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);
}
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc
index 9a3e3bbc..a80fdec2 100644
--- a/src/subtitle_asset.cc
+++ b/src/subtitle_asset.cc
@@ -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)
{
}
diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h
index d272957e..607b054d 100644
--- a/src/subtitle_asset.h
+++ b/src/subtitle_asset.h
@@ -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
diff --git a/src/xml.cc b/src/xml.cc
index b9ee56a8..35c4fe12 100644
--- a/src/xml.cc
+++ b/src/xml.cc
@@ -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
diff --git a/test/tests.cc b/test/tests.cc
index c47e8938..2893cc6b 100644
--- a/test/tests.cc
+++ b/test/tests.cc
@@ -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)