*/
#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)
}
}
+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)
{
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;
+}
, t (t_)
{}
+ Time (std::string time);
+
int h; ///< hours
int m; ///< minutes
int s; ///< seconds
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);
}
*/
+#include <boost/lexical_cast.hpp>
#include "subtitle_asset.h"
using namespace std;
(*k)->v_align,
(*k)->text,
effective.effect.get(),
- effective.effect_color.get()
+ effective.effect_color.get(),
+ (*k)->fade_up_time,
+ (*k)->fade_down_time
)
)
);
} 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> >
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)
, _text (text)
, _effect (effect)
, _effect_color (effect_color)
+ , _fade_up_time (fade_up_time)
+ , _fade_down_time (fade_down_time)
{
}
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
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 {
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:
std::string _text;
Effect _effect;
Color _effect_color;
+ Time _fade_up_time;
+ Time _fade_down_time;
};
class SubtitleAsset : public Asset, public XMLFile
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
*/
+#include <cmath>
#include <boost/filesystem.hpp>
#include "KM_prng.h"
#include "dcp.h"
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)