summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-01-13 23:04:11 +0000
committerCarl Hetherington <cth@carlh.net>2015-01-13 23:04:11 +0000
commitf1ba458a19a9b998ecdb1db726106876953abcc0 (patch)
tree1e414103fec758275f92dff3b7973cc02dbf39a3 /src
parentd15ef17dccf87b633d1971c38032a2049abe3db0 (diff)
Various development / fixes.rework
Diffstat (limited to 'src')
-rw-r--r--src/exceptions.h7
-rw-r--r--src/font_size.cc12
-rw-r--r--src/font_size.h5
-rw-r--r--src/sub_time.cc160
-rw-r--r--src/sub_time.h14
-rw-r--r--src/subtitle.cc107
-rw-r--r--src/subtitle.h9
-rw-r--r--src/wscript3
8 files changed, 315 insertions, 2 deletions
diff --git a/src/exceptions.h b/src/exceptions.h
index 8602517..0531279 100644
--- a/src/exceptions.h
+++ b/src/exceptions.h
@@ -107,6 +107,13 @@ public:
{}
};
+class MismatchedFrameRateException : public MessageError
+{
+public:
+ MismatchedFrameRateException ()
+ : MessageError ("cannot perform this operation with different frame rates")
+ {}
+};
}
#endif
diff --git a/src/font_size.cc b/src/font_size.cc
index d11ee89..7d556af 100644
--- a/src/font_size.cc
+++ b/src/font_size.cc
@@ -40,3 +40,15 @@ FontSize::points (int screen_height_in_points) const
return _proportional.get() * screen_height_in_points;
}
+
+bool
+FontSize::operator== (FontSize const & other) const
+{
+ if (_proportional && other._proportional) {
+ return _proportional.get() == other._proportional.get();
+ } else if (_points && other._points) {
+ return _points.get() == other._points.get();
+ }
+
+ return false;
+}
diff --git a/src/font_size.h b/src/font_size.h
index 0b4b357..6c3a284 100644
--- a/src/font_size.h
+++ b/src/font_size.h
@@ -20,6 +20,8 @@
#ifndef LIBSUB_FONT_SIZE_H
#define LIBSUB_FONT_SIZE_H
+#include <boost/optional.hpp>
+
namespace sub {
/** @class FontSize
@@ -48,7 +50,10 @@ public:
}
float proportional (int screen_height_in_points) const;
+ int pixels (int screen_height_in_points) const;
int points (int screen_height_in_points) const;
+
+ bool operator== (FontSize const & other) const;
private:
/** as a proportion of screen height */
diff --git a/src/sub_time.cc b/src/sub_time.cc
index 780dbc9..9c7b98b 100644
--- a/src/sub_time.cc
+++ b/src/sub_time.cc
@@ -86,6 +86,46 @@ Time::from_hmsm (int h, int m, int s, int ms)
return Time (h, m, s, ms, optional<int> (), optional<FrameRate> ());
}
+Time
+Time::from_frames (int64_t f, FrameRate r)
+{
+ double s = f / enum_to_value (r);
+ int const hours = floor (s / 3600);
+ s -= hours * 3600;
+ int const minutes = floor (s / 60);
+ s -= minutes * 60;
+ int const seconds = floor (s);
+ s -= seconds;
+ int const frames = rint (s * enum_to_value (r));
+
+ return Time::from_hmsf (hours, minutes, seconds, frames, r);
+}
+
+Time
+Time::from_milliseconds (int64_t m)
+{
+ int const hours = m / 3600000;
+ m -= hours * 3600000;
+ int const minutes = m / 60000;
+ m -= minutes * 60000;
+ int const seconds = m / 1000;
+ m -= seconds * 1000;
+
+ return Time (hours, minutes, seconds, m, optional<int> (), optional<FrameRate> ());
+}
+
+bool
+Time::operator<= (Time const & other) const
+{
+ return *this < other || *this == other;
+}
+
+bool
+Time::operator>= (Time const & other) const
+{
+ return *this > other || *this == other;
+}
+
bool
Time::operator< (Time const & other) const
{
@@ -159,7 +199,7 @@ Time::operator== (Time const & other) const
}
/* Otherwise we have to do it by comparing milliseconds */
- return abs (as_milliseconds() - other.as_milliseconds()) <= 1;
+ return as_milliseconds() == other.as_milliseconds();
}
bool
@@ -184,6 +224,124 @@ sub::operator<< (ostream& s, Time const & t)
return s;
}
+Time
+sub::operator+ (Time const & a, Time const & b)
+{
+ int seconds = 0;
+ int minutes = 0;
+ int hours = 0;
+
+ optional<int> frames;
+ optional<FrameRate> frame_rate;
+ optional<int> milliseconds;
+
+ if (a._frames && b._frames) {
+ if (!a._frame_rate || !b._frame_rate) {
+ throw UnknownFrameRateException ();
+ }
+ if (a._frame_rate.get() != b._frame_rate.get()) {
+ throw MismatchedFrameRateException ();
+ }
+
+ frame_rate = a._frame_rate.get ();
+ frames = a._frames.get() + b._frames.get();
+ if (frames.get() >= enum_to_value (frame_rate.get ())) {
+ frames = frames.get() - enum_to_value (frame_rate.get ());
+ ++seconds;
+ }
+ } else if (a._milliseconds && b._milliseconds) {
+ milliseconds = a._milliseconds.get() + b._milliseconds.get();
+ if (milliseconds >= 1000) {
+ milliseconds = milliseconds.get() - 1000;
+ ++seconds;
+ }
+ } else {
+ return Time::from_milliseconds (a.as_milliseconds() + b.as_milliseconds());
+ }
+
+ seconds += a.seconds + b.seconds;
+ if (seconds >= 60) {
+ seconds -= 60;
+ ++minutes;
+ }
+
+ minutes += a.minutes + b.minutes;
+ if (minutes >= 60) {
+ minutes -= 60;
+ ++hours;
+ }
+
+ hours += a.hours + b.hours;
+
+ if (frames) {
+ return sub::Time (hours, minutes, seconds, optional<int> (), frames.get(), frame_rate.get());
+ } else {
+ return sub::Time (hours, minutes, seconds, milliseconds.get(), optional<int> (), optional<FrameRate> ());
+ }
+}
+
+Time
+sub::operator- (Time const & a, Time const & b)
+{
+ int seconds = 0;
+ int minutes = 0;
+ int hours = 0;
+
+ optional<int> frames;
+ optional<FrameRate> frame_rate;
+ optional<int> milliseconds;
+
+ if (a._frames && b._frames) {
+ if (!a._frame_rate || !b._frame_rate) {
+ throw UnknownFrameRateException ();
+ }
+ if (a._frame_rate.get() != b._frame_rate.get()) {
+ throw MismatchedFrameRateException ();
+ }
+
+ frame_rate = a._frame_rate.get ();
+ frames = a._frames.get() - b._frames.get();
+ if (frames.get() < 0) {
+ frames = frames.get() + enum_to_value (frame_rate.get ());
+ --seconds;
+ }
+ } else if (a._milliseconds && b._milliseconds) {
+ milliseconds = a._milliseconds.get() - b._milliseconds.get();
+ if (milliseconds < 0) {
+ milliseconds = milliseconds.get() + 1000;
+ --seconds;
+ }
+ } else {
+ return Time::from_milliseconds (a.as_milliseconds() - b.as_milliseconds());
+ }
+
+ seconds += a.seconds - b.seconds;
+ if (seconds < 0) {
+ seconds += 60;
+ --minutes;
+ }
+
+ minutes += a.minutes - b.minutes;
+ if (minutes < 0) {
+ minutes += 60;
+ --hours;
+ }
+
+ hours += a.hours - b.hours;
+
+ if (frames) {
+ return sub::Time (hours, minutes, seconds, optional<int> (), frames.get(), frame_rate.get());
+ } else {
+ return sub::Time (hours, minutes, seconds, milliseconds.get(), optional<int> (), optional<FrameRate> ());
+ }
+}
+
+double
+sub::operator/ (Time const & a, Time const & b)
+{
+ return double (a.as_milliseconds()) / b.as_milliseconds();
+}
+
Time::Time (int h, int m, int s, optional<int> ms, optional<int> f, optional<FrameRate> r)
: hours (h)
, minutes (m)
diff --git a/src/sub_time.h b/src/sub_time.h
index 4b3f0e1..48a868c 100644
--- a/src/sub_time.h
+++ b/src/sub_time.h
@@ -40,6 +40,10 @@ public:
int minutes;
int seconds;
+ boost::optional<int> frames () const {
+ return _frames;
+ }
+
/** @return the frames part of the time at a particular frame rate */
int frames (FrameRate r) const;
@@ -50,14 +54,21 @@ public:
static Time from_hmsf (int h, int m, int s, int f, FrameRate r);
static Time from_hms (int h, int m, double s);
static Time from_hmsm (int h, int m, int s, int ms);
+ static Time from_frames (int64_t f, FrameRate r);
+ static Time from_milliseconds (int64_t ms);
bool operator== (Time const & other) const;
bool operator!= (Time const & other) const;
bool operator< (Time const & other) const;
+ bool operator<= (Time const & other) const;
bool operator> (Time const & other) const;
+ bool operator>= (Time const & other) const;
private:
friend std::ostream & operator<< (std::ostream& s, Time const & t);
+ friend Time operator+ (Time const & a, Time const & b);
+ friend Time operator- (Time const & a, Time const & b);
+ friend double operator/ (Time const & a, Time const & b);
friend struct ::time_construction_test;
@@ -69,6 +80,9 @@ private:
};
std::ostream& operator<< (std::ostream& s, Time const & t);
+Time operator+ (Time const & a, Time const & b);
+Time operator- (Time const & a, Time const & b);
+double operator/ (Time const & a, Time const & b);
}
diff --git a/src/subtitle.cc b/src/subtitle.cc
index dc316c3..231abc6 100644
--- a/src/subtitle.cc
+++ b/src/subtitle.cc
@@ -19,6 +19,8 @@
#include "subtitle.h"
+using std::ostream;
+using std::list;
using namespace sub;
Subtitle::Subtitle (RawSubtitle s)
@@ -56,6 +58,18 @@ Subtitle::same_metadata (RawSubtitle s) const
return true;
}
+bool
+sub::operator== (Subtitle const & a, Subtitle const & b)
+{
+ return (
+ a.from == b.from &&
+ a.to == b.to &&
+ a.fade_up == b.fade_up &&
+ a.fade_down == b.fade_down &&
+ a.lines == b.lines
+ );
+}
+
Line::Line (RawSubtitle s)
: vertical_position (s.vertical_position)
{
@@ -68,6 +82,15 @@ Line::same_metadata (RawSubtitle s) const
return vertical_position == s.vertical_position;
}
+bool
+sub::operator== (Line const & a, Line const & b)
+{
+ return (
+ a.vertical_position == b.vertical_position &&
+ a.blocks == b.blocks
+ );
+}
+
Block::Block (RawSubtitle s)
: text (s.text)
, font (s.font)
@@ -81,3 +104,87 @@ Block::Block (RawSubtitle s)
{
}
+
+bool
+sub::operator== (Block const & a, Block const & b)
+{
+ return (
+ a.text == b.text &&
+ a.font == b.font &&
+ a.font_size == b.font_size &&
+ a.effect == b.effect &&
+ a.effect_colour == b.effect_colour &&
+ a.colour == b.colour &&
+ a.bold == b.bold &&
+ a.italic == b.italic &&
+ a.underline == b.underline
+ );
+}
+
+/* The output of this method should not be relied upon
+ as part of the API.
+*/
+ostream &
+sub::operator<< (ostream& s, Subtitle const & sub)
+{
+ s << "Subtitle at " << sub.from << " -> " << sub.to << "\n";
+ for (list<sub::Line>::const_iterator i = sub.lines.begin(); i != sub.lines.end(); ++i) {
+
+ s << "\t";
+
+ /* XXX: should be in VerticalPosition operator<< */
+ if (i->vertical_position.proportional) {
+ s << i->vertical_position.proportional.get() << " of screen";
+ } else if (i->vertical_position.line) {
+ s << i->vertical_position.line.get() << " lines of " << i->vertical_position.lines.get();
+ }
+ if (i->vertical_position.reference) {
+ s << " from ";
+ switch (i->vertical_position.reference.get()) {
+ case TOP_OF_SCREEN:
+ s << "top";
+ break;
+ case CENTRE_OF_SCREEN:
+ s << "centre";
+ break;
+ case BOTTOM_OF_SCREEN:
+ s << "bottom";
+ break;
+ case TOP_OF_SUBTITLE:
+ s << "top of subtitle";
+ break;
+ }
+ }
+
+ s << "\t";
+ bool italic = false;
+ bool underline = false;
+ for (list<sub::Block>::const_iterator j = i->blocks.begin(); j != i->blocks.end(); ++j) {
+ if (j->italic && !italic) {
+ s << "<i>";
+ } else if (italic && !j->italic) {
+ s << "</i>";
+ }
+ if (j->underline && !underline) {
+ s << "<u>";
+ } else if (underline && !j->underline) {
+ s << "</u>";
+ }
+
+ italic = j->italic;
+ underline = j->underline;
+
+ s << j->text;
+ }
+
+ if (italic) {
+ s << "</i>";
+ }
+ if (underline) {
+ s << "</u>";
+ }
+ s << "\n";
+ }
+
+ return s;
+}
diff --git a/src/subtitle.h b/src/subtitle.h
index d747a60..582823b 100644
--- a/src/subtitle.h
+++ b/src/subtitle.h
@@ -67,6 +67,8 @@ public:
bool underline; ///< true to underline
};
+bool operator== (Block const & a, Block const & b);
+
/** @class Line
* @brief A line of text within a subtitle.
*
@@ -88,6 +90,8 @@ public:
bool same_metadata (RawSubtitle) const;
};
+bool operator== (Line const & a, Line const & b);
+
/** @class Subtitle
* @brief A subtitle which has been collected into lines and blocks.
*
@@ -102,7 +106,7 @@ public:
/** Construct a Line taking any relevant information from a RawSubtitle */
Subtitle (RawSubtitle s);
-
+
/** from time */
Time from;
/** to time */
@@ -116,6 +120,9 @@ public:
bool same_metadata (RawSubtitle) const;
};
+bool operator== (Subtitle const & a, Subtitle const & b);
+std::ostream & operator<< (std::ostream &, Subtitle const & sub);
+
}
#endif
diff --git a/src/wscript b/src/wscript
index b1a4ca4..c4f1d44 100644
--- a/src/wscript
+++ b/src/wscript
@@ -15,6 +15,7 @@ def build(bld):
colour.cc
dcp_reader.cc
effect.cc
+ font_size.cc
frame_rate.cc
interop_dcp_reader.cc
iso6937.cc
@@ -47,6 +48,7 @@ def build(bld):
dcp_reader.h
effect.h
font_size.h
+ frame_rate.h
raw_subtitle.h
reader.h
reader_factory.h
@@ -54,6 +56,7 @@ def build(bld):
stl_binary_tables.h
stl_binary_writer.h
stl_text_reader.h
+ sub_time.h
subrip_reader.h
subtitle.h
vertical_position.h