};
+class WebVTTHeaderError : public WebVTTError
+{
+public:
+ WebVTTHeaderError()
+ : WebVTTError("No WEBVTT header found")
+ {}
+};
+
+
class SSAError : public std::runtime_error
{
public:
}
} else if (keys[i] == "MarginV") {
vertical_margin = raw_convert<int> (style[i]);
+ } else if (keys[i] == "MarginL") {
+ left_margin = raw_convert<int>(style[i]);
+ } else if (keys[i] == "MarginR") {
+ right_margin = raw_convert<int>(style[i]);
}
}
}
HorizontalReference horizontal_reference;
VerticalReference vertical_reference;
int vertical_margin;
+ int left_margin = 0;
+ int right_margin = 0;
private:
Colour colour (string c) const
}
};
+
+void
+SSAReader::Context::update_horizontal_position(RawSubtitle& sub) const
+{
+ switch (sub.horizontal_position.reference) {
+ case LEFT_OF_SCREEN:
+ sub.horizontal_position.proportional = static_cast<float>(left_margin) / play_res_x;
+ break;
+ case HORIZONTAL_CENTRE_OF_SCREEN:
+ sub.horizontal_position.proportional = static_cast<float>(left_margin - right_margin) / (2 * play_res_x);
+ break;
+ case RIGHT_OF_SCREEN:
+ sub.horizontal_position.proportional = static_cast<float>(right_margin) / play_res_x;
+ break;
+ }
+}
+
+
Time
SSAReader::parse_time (string t) const
{
);
}
+
void
-SSAReader::parse_style(RawSubtitle& sub, string style, int play_res_x, int play_res_y, Colour primary_colour)
+SSAReader::parse_tag(RawSubtitle& sub, string tag, Context const& context)
{
- if (style == "\\i1") {
+ if (tag == "\\i1") {
sub.italic = true;
- } else if (style == "\\i0" || style == "\\i") {
+ } else if (tag == "\\i0" || tag == "\\i") {
sub.italic = false;
- } else if (style == "\\b1") {
+ } else if (tag == "\\b1") {
sub.bold = true;
- } else if (style == "\\b0") {
+ } else if (tag == "\\b0") {
sub.bold = false;
- } else if (style == "\\u1") {
+ } else if (tag == "\\u1") {
sub.underline = true;
- } else if (style == "\\u0") {
+ } else if (tag == "\\u0") {
sub.underline = false;
- } else if (style == "\\an1") {
+ } else if (tag == "\\an1") {
sub.horizontal_position.reference = sub::LEFT_OF_SCREEN;
sub.vertical_position.reference = sub::BOTTOM_OF_SCREEN;
- } else if (style == "\\an2") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an2") {
sub.horizontal_position.reference = sub::HORIZONTAL_CENTRE_OF_SCREEN;
sub.vertical_position.reference = sub::BOTTOM_OF_SCREEN;
- } else if (style == "\\an3") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an3") {
sub.horizontal_position.reference = sub::RIGHT_OF_SCREEN;
sub.vertical_position.reference = sub::BOTTOM_OF_SCREEN;
- } else if (style == "\\an4") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an4") {
sub.horizontal_position.reference = sub::LEFT_OF_SCREEN;
sub.vertical_position.reference = sub::VERTICAL_CENTRE_OF_SCREEN;
- } else if (style == "\\an5") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an5") {
sub.horizontal_position.reference = sub::HORIZONTAL_CENTRE_OF_SCREEN;
sub.vertical_position.reference = sub::VERTICAL_CENTRE_OF_SCREEN;
- } else if (style == "\\an6") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an6") {
sub.horizontal_position.reference = sub::RIGHT_OF_SCREEN;
sub.vertical_position.reference = sub::VERTICAL_CENTRE_OF_SCREEN;
- } else if (style == "\\an7") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an7") {
sub.horizontal_position.reference = sub::LEFT_OF_SCREEN;
sub.vertical_position.reference = sub::TOP_OF_SCREEN;
- } else if (style == "\\an8") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an8") {
sub.horizontal_position.reference = sub::HORIZONTAL_CENTRE_OF_SCREEN;
sub.vertical_position.reference = sub::TOP_OF_SCREEN;
- } else if (style == "\\an9") {
+ context.update_horizontal_position(sub);
+ } else if (tag == "\\an9") {
sub.horizontal_position.reference = sub::RIGHT_OF_SCREEN;
sub.vertical_position.reference = sub::TOP_OF_SCREEN;
- } else if (boost::starts_with(style, "\\pos")) {
+ context.update_horizontal_position(sub);
+ } else if (boost::starts_with(tag, "\\pos")) {
vector<string> bits;
- boost::algorithm::split (bits, style, boost::is_any_of("(,"));
+ boost::algorithm::split (bits, tag, boost::is_any_of("(,"));
SUB_ASSERT (bits.size() == 3);
sub.horizontal_position.reference = sub::LEFT_OF_SCREEN;
- sub.horizontal_position.proportional = raw_convert<float>(bits[1]) / play_res_x;
+ sub.horizontal_position.proportional = raw_convert<float>(bits[1]) / context.play_res_x;
sub.vertical_position.reference = sub::TOP_OF_SCREEN;
- sub.vertical_position.proportional = raw_convert<float>(bits[2]) / play_res_y;
- } else if (boost::starts_with(style, "\\fs")) {
- SUB_ASSERT (style.length() > 3);
- sub.font_size.set_proportional(raw_convert<float>(style.substr(3)) / play_res_y);
- } else if (boost::starts_with(style, "\\c")) {
+ sub.vertical_position.proportional = raw_convert<float>(bits[2]) / context.play_res_y;
+ } else if (boost::starts_with(tag, "\\fs")) {
+ SUB_ASSERT (tag.length() > 3);
+ sub.font_size.set_proportional(raw_convert<float>(tag.substr(3)) / context.play_res_y);
+ } else if (boost::starts_with(tag, "\\c")) {
/* \c&Hbbggrr& */
- if (style.length() > 2) {
- sub.colour = h_colour(style.substr(2, style.length() - 3));
- } else if (style.length() == 2) {
- sub.colour = primary_colour;
+ if (tag.length() > 2) {
+ sub.colour = h_colour(tag.substr(2, tag.length() - 3));
+ } else if (tag.length() == 2) {
+ sub.colour = context.primary_colour;
} else {
- throw SSAError(String::compose("Badly formatted colour tag %1", style));
+ throw SSAError(String::compose("Badly formatted colour tag %1", tag));
}
}
}
* @return List of RawSubtitles to represent line with vertical reference TOP_OF_SUBTITLE.
*/
vector<RawSubtitle>
-SSAReader::parse_line(RawSubtitle base, string line, int play_res_x, int play_res_y, Colour primary_colour)
+SSAReader::parse_line(RawSubtitle base, string line, Context const& context)
{
enum {
TEXT,
- STYLE,
+ TAG,
BACKSLASH
} state = TEXT;
vector<RawSubtitle> subs;
RawSubtitle current = base;
- string style;
+ string tag;
if (!current.vertical_position.reference) {
current.vertical_position.reference = BOTTOM_OF_SCREEN;
*/
current.vertical_position.proportional = 0;
+ context.update_horizontal_position(current);
+
/* We must have a font size, as there could be a margin specified
in pixels and in that case we must know how big the subtitle
lines are to work out the position on screen.
*/
if (!current.font_size.proportional()) {
- current.font_size.set_proportional(72.0 / play_res_y);
+ current.font_size.set_proportional(72.0 / context.play_res_y);
}
/* Count the number of line breaks */
}
/* There are vague indications that with ASS 1 point should equal 1 pixel */
- double const line_size = current.font_size.proportional(play_res_y) * 1.2;
+ double const line_size = current.font_size.proportional(context.play_res_y) * 1.2;
for (size_t i = 0; i < line.length(); ++i) {
char const c = line[i];
switch (state) {
case TEXT:
if (c == '{') {
- state = STYLE;
+ state = TAG;
} else if (c == '\\') {
state = BACKSLASH;
} else if (c != '\r' && c != '\n') {
current.text += c;
}
break;
- case STYLE:
+ case TAG:
if (c == '}' || c == '\\') {
if (!current.text.empty ()) {
subs.push_back (current);
current.text = "";
}
- parse_style(current, style, play_res_x, play_res_y, primary_colour);
- style = "";
+ parse_tag(current, tag, context);
+ tag = "";
}
if (c == '}') {
state = TEXT;
} else {
- style += c;
+ tag += c;
}
break;
case BACKSLASH:
RawSubtitle sub;
optional<Style> style;
+ int left_margin = 0;
+ int right_margin = 0;
for (size_t i = 0; i < event.size(); ++i) {
trim (event[i]);
if (sub.vertical_position.reference != sub::VERTICAL_CENTRE_OF_SCREEN) {
sub.vertical_position.proportional = float(style->vertical_margin) / play_res_y;
}
+ left_margin = style->left_margin;
+ right_margin = style->right_margin;
} else if (event_format[i] == "MarginV") {
if (event[i] != "0" && sub.vertical_position.reference != sub::VERTICAL_CENTRE_OF_SCREEN) {
/* Override the style if its non-zero */
sub.vertical_position.proportional = raw_convert<float>(event[i]) / play_res_y;
}
+ } else if (event_format[i] == "MarginL") {
+ if (event[i] != "0") {
+ left_margin = raw_convert<int>(event[i]);
+ }
+ } else if (event_format[i] == "MarginR") {
+ if (event[i] != "0") {
+ right_margin = raw_convert<int>(event[i]);
+ }
} else if (event_format[i] == "Text") {
- for (auto j: parse_line(sub, event[i], play_res_x, play_res_y, style ? style->primary_colour : Colour(1, 1, 1))) {
+ auto context = Context(play_res_x, play_res_y, style ? style->primary_colour : Colour(1, 1, 1), left_margin, right_margin);
+ for (auto j: parse_line(sub, event[i], context)) {
_subs.push_back (j);
}
}
SSAReader (FILE* f);
SSAReader (std::string subs);
- static std::vector<RawSubtitle> parse_line(RawSubtitle base, std::string line, int play_res_x, int play_res_y, Colour primary_colour);
- static void parse_style(RawSubtitle& sub, std::string style, int play_res_x, int play_res_y, Colour primary_colour);
+ class Context
+ {
+ public:
+ Context(int play_res_x_, int play_res_y_, Colour primary_colour_, int left_margin_ = 0, int right_margin_ = 0)
+ : play_res_x(play_res_x_)
+ , play_res_y(play_res_y_)
+ , primary_colour(primary_colour_)
+ , left_margin(left_margin_)
+ , right_margin(right_margin_)
+ {}
+
+ int play_res_x;
+ int play_res_y;
+ Colour primary_colour;
+ int left_margin;
+ int right_margin;
+
+ void update_horizontal_position(RawSubtitle& sub) const;
+ };
+
+ static std::vector<RawSubtitle> parse_line(RawSubtitle base, std::string line, Context const& context);
+ static void parse_tag(RawSubtitle& sub, std::string style, Context const& context);
private:
void read (boost::function<boost::optional<std::string> ()> get_line);
break;
}
- if (c >= 0x80 && c <= 0x83) {
- /* Italic or underline control code */
+ if (c <= 0x07 || (c >= 0x80 && c <= 0x83)) {
+ /* Colour, italic or underline control code */
sub.text = utf_to_utf<char> (iso6937_to_utf16 (text.c_str()));
_subs.push_back (sub);
text.clear ();
}
switch (c) {
+ case 0x0:
+ /* Black */
+ sub.colour = Colour(0, 0, 0);
+ break;
+ case 0x1:
+ /* Red */
+ sub.colour = Colour(1, 0, 0);
+ break;
+ case 0x2:
+ /* Lime */
+ sub.colour = Colour(0, 1, 0);
+ break;
+ case 0x3:
+ /* Yellow */
+ sub.colour = Colour(1, 1, 0);
+ break;
+ case 0x4:
+ /* Blue */
+ sub.colour = Colour(0, 0, 1);
+ break;
+ case 0x5:
+ /* Magenta */
+ sub.colour = Colour(1, 0, 1);
+ break;
+ case 0x6:
+ /* Cyan */
+ sub.colour = Colour(0, 1, 1);
+ break;
+ case 0x7:
+ /* White */
+ sub.colour = Colour(1, 1, 1);
+ break;
case 0x80:
italic = true;
break;
++i;
}
++i;
- SSAReader::parse_style (p, ssa, 288, 288, Colour(1, 1, 1));
+ SSAReader::parse_tag(p, ssa, SSAReader::Context{288, 288, Colour(1, 1, 1)});
} else {
p.text += t[i];
++i;
switch (state) {
case State::HEADER:
if (!boost::starts_with(*line, "WEBVTT")) {
- throw WebVTTError("No WEBVTT header found");
+ throw WebVTTHeaderError();
}
state = State::DATA;
break;
--- /dev/null
+[Script Info]
+Title: libsub test
+ScriptType: v4.00
+WrapStyle: 0
+ScaledBorderAndShadow: yes
+PlayResX: 1920
+PlayResY: 1080
+
+[V4 Styles]
+Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, TertiaryColour, BackColour, Bold, Italic, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, AlphaLevel, Encoding
+Style: Default,Arial,20,16777215,255,0,0,0,0,1,2,2,2,200,100,10,0,1
+
+[Fonts]
+
+[Graphics]
+
+[Events]
+Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
+Dialogue: Marked=0,0:00:01.23,0:00:04.55,Default,,100,0,0,,Hello world
+Dialogue: Marked=0,0:01:01.23,0:01:04.55,Default,,10,0,0,,Left of centre
+Dialogue: Marked=0,0:02:01.23,0:02:04.55,Default,,10,0,0,,{\an4}Left
+Dialogue: Marked=0,0:03:01.23,0:03:04.55,Default,,10,0,0,,{\an6}Right
+Dialogue: Marked=0,0:04:01.23,0:04:04.55,Default,,0,100,0,,{\an4}Style left
using std::vector;
+static
+vector<sub::Subtitle>
+read_file(boost::filesystem::path filename)
+{
+ auto file = fopen(filename.string().c_str(), "r");
+ BOOST_REQUIRE(file);
+ sub::SSAReader reader(file);
+ fclose(file);
+ return sub::collect<vector<sub::Subtitle>>(reader.subtitles());
+}
+
BOOST_AUTO_TEST_CASE (ssa_reader_test)
{
- boost::filesystem::path p = private_test / "example.ssa";
- FILE* f = fopen (p.string().c_str(), "r");
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file(private_test / "example.ssa");
auto i = subs.begin ();
auto r = sub::SSAReader::parse_line (
base,
"This is a line with some {\\i1}italics{\\i0} and then\\nthere is a new line.",
- 1920, 1080,
- sub::Colour(1, 1, 1)
+ sub::SSAReader::Context(1920, 1080, sub::Colour(1, 1, 1))
);
auto i = r.begin();
auto r = sub::SSAReader::parse_line (
base,
"{\\i1}It's all just italics{\\i0}",
- 1920, 1080,
- sub::Colour(1, 1, 1)
+ sub::SSAReader::Context(1920, 1080, sub::Colour(1, 1, 1))
);
/* Convert a font size in points to a vertical position for this file */
r = sub::SSAReader::parse_line (
base,
"{\\i1}Italic{\\i0}\\Nand new line",
- 1920, 1080,
- sub::Colour(1, 1, 1)
+ sub::SSAReader::Context(1920, 1080, sub::Colour(1, 1, 1))
);
i = r.begin ();
static void
test (boost::filesystem::path p)
{
- p = private_test / p;
- FILE* f = fopen (p.string().c_str(), "r");
- BOOST_REQUIRE (f);
- sub::SSAReader r (f);
- fclose (f);
+ read_file(private_test / p);
}
/** Test of reading some typical .ssa files */
/** Test reading of a file within the libsub tree which exercises the parser */
BOOST_AUTO_TEST_CASE (ssa_reader_test3)
{
- boost::filesystem::path p = "test/data/test.ssa";
- FILE* f = fopen (p.string().c_str(), "r");
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file("test/data/test.ssa");
/* Convert a font size in points to a proportional size for this file */
auto fs = [](int x) {
/* Alignments */
SUB_START (sub::Time::from_hms (0, 0, 9, 230), sub::Time::from_hms (0, 0, 11, 560));
- LINE ((10.0 / 1080), sub::BOTTOM_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
+ LINE ((10.0 / 1080), sub::BOTTOM_OF_SCREEN, (10.0 / 1920), sub::LEFT_OF_SCREEN);
BLOCK("bottom left", "Arial", fs(20), false, false, false);
SUB_END ();
SUB_END ();
SUB_START (sub::Time::from_hms (0, 0, 9, 250), sub::Time::from_hms (0, 0, 11, 560));
- LINE ((10.0 / 1080), sub::BOTTOM_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
+ LINE ((10.0 / 1080), sub::BOTTOM_OF_SCREEN, (10.0 / 1920), sub::RIGHT_OF_SCREEN);
BLOCK("bottom right", "Arial", fs(20), false, false, false);
SUB_END ();
SUB_START (sub::Time::from_hms (0, 0, 9, 260), sub::Time::from_hms (0, 0, 11, 560));
/* Position is half of a 20pt line (with line spacing) above vertical centre */
- LINE (-vp(10), sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
+ LINE (-vp(10), sub::VERTICAL_CENTRE_OF_SCREEN, (10.0 / 1920), sub::LEFT_OF_SCREEN);
BLOCK("middle left", "Arial", fs(20), false, false, false);
SUB_END ();
SUB_END ();
SUB_START (sub::Time::from_hms (0, 0, 9, 280), sub::Time::from_hms (0, 0, 11, 560));
- LINE (-vp(10), sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
+ LINE (-vp(10), sub::VERTICAL_CENTRE_OF_SCREEN, (10.0 / 1920), sub::RIGHT_OF_SCREEN);
BLOCK("middle right", "Arial", fs(20), false, false, false);
SUB_END ();
SUB_START (sub::Time::from_hms (0, 0, 9, 290), sub::Time::from_hms (0, 0, 11, 560));
- LINE ((10.0 / 1080), sub::TOP_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
+ LINE ((10.0 / 1080), sub::TOP_OF_SCREEN, (10.0 / 1920), sub::LEFT_OF_SCREEN);
BLOCK("top left", "Arial", fs(20), false, false, false);
SUB_END ();
SUB_END ();
SUB_START (sub::Time::from_hms (0, 0, 9, 310), sub::Time::from_hms (0, 0, 11, 560));
- LINE ((10.0 / 1080), sub::TOP_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
+ LINE ((10.0 / 1080), sub::TOP_OF_SCREEN, (10.0 / 1920), sub::RIGHT_OF_SCREEN);
BLOCK("top right", "Arial", fs(20), false, false, false);
SUB_END ();
/** Test reading of a file within the libsub-test-private tree which exercises the parser */
BOOST_AUTO_TEST_CASE (ssa_reader_test4)
{
- boost::filesystem::path p = private_test / "dcpsubtest2-en.ssa";
- FILE* f = fopen (p.string().c_str(), "r");
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file(private_test / "dcpsubtest2-en.ssa");
auto i = subs.begin();
vector<sub::Line>::iterator j;
/** Test reading of a .ass file */
BOOST_AUTO_TEST_CASE (ssa_reader_test5)
{
- boost::filesystem::path p = private_test / "dcpsubtest-en.ass";
- FILE* f = fopen (p.string().c_str(), "r");
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file(private_test / "dcpsubtest-en.ass");
/* Convert a font size in points to a proportional size for this file */
auto fs = [](int x) {
/** Test reading of another .ass file */
BOOST_AUTO_TEST_CASE (ssa_reader_test6)
{
- boost::filesystem::path p = private_test / "DCP-o-matic_test_subs_1.ass";
- auto f = fopen (p.string().c_str(), "r");
- BOOST_REQUIRE (f);
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file(private_test / "DCP-o-matic_test_subs_1.ass");
/* Convert a font size in points to a proportional size for this file */
auto fs = [](int x) {
BOOST_AUTO_TEST_CASE (ssa_reader_test7)
{
- auto p = boost::filesystem::path("test") / "data" / "test3.ssa";
- auto f = fopen(p.string().c_str(), "r");
- BOOST_REQUIRE(f);
- sub::SSAReader reader(f);
- fclose(f);
- auto subs = sub::collect<vector<sub::Subtitle>>(reader.subtitles());
+ auto subs = read_file("test/data/test3.ssa");
/* Convert a font size in points to a proportional size for this file */
auto fs = [](int x) {
/** Test \pos */
BOOST_AUTO_TEST_CASE (ssa_reader_pos)
{
- boost::filesystem::path p = "test/data/test2.ssa";
- FILE* f = fopen (p.string().c_str(), "r");
- sub::SSAReader reader (f);
- fclose (f);
- auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
+ auto subs = read_file("test/data/test2.ssa");
/* Convert a font size in points to a proportional size for this file */
auto fs = [](int x) {
auto r = sub::SSAReader::parse_line (
base,
"This is a line with some {\\fs64}font sizing.",
- 1920, 1080,
- sub::Colour(1, 1, 1)
+ sub::SSAReader::Context(1920, 1080, sub::Colour(1, 1, 1))
);
auto i = r.begin ();
auto r = sub::SSAReader::parse_line (
base,
String::compose("{\\c%1}Hello world", command),
- 1920, 1080,
- sub::Colour(1, 0, 1)
+ sub::SSAReader::Context(1920, 1080, sub::Colour(1, 0, 1))
);
auto i = r.begin ();
test_c("", "ff00ff");
}
+
+BOOST_AUTO_TEST_CASE(ssa_reader_horizontal_margin)
+{
+ auto subs = read_file("test/data/horizontal_margin.ssa");
+ BOOST_REQUIRE_EQUAL(subs.size(), 5U);
+
+ int n = 0;
+
+ BOOST_REQUIRE_EQUAL(subs[n].lines.size(), 1U);
+ BOOST_CHECK(subs[n].lines[0].horizontal_position.reference == sub::HORIZONTAL_CENTRE_OF_SCREEN);
+ BOOST_CHECK_CLOSE(subs[n].lines[0].horizontal_position.proportional, 0, 1);
+ ++n;
+
+ BOOST_REQUIRE_EQUAL(subs[n].lines.size(), 1U);
+ BOOST_CHECK(subs[n].lines[0].horizontal_position.reference == sub::HORIZONTAL_CENTRE_OF_SCREEN);
+ BOOST_CHECK_CLOSE(subs[n].lines[0].horizontal_position.proportional, -90.0f / (2 * 1920.0f), 1);
+ ++n;
+
+ BOOST_REQUIRE_EQUAL(subs[n].lines.size(), 1U);
+ BOOST_CHECK(subs[n].lines[0].horizontal_position.reference == sub::LEFT_OF_SCREEN);
+ BOOST_CHECK_CLOSE(subs[n].lines[0].horizontal_position.proportional, 10.0f / 1920.f, 1);
+ ++n;
+
+ BOOST_REQUIRE_EQUAL(subs[n].lines.size(), 1U);
+ BOOST_CHECK(subs[n].lines[0].horizontal_position.reference == sub::RIGHT_OF_SCREEN);
+ BOOST_CHECK_CLOSE(subs[n].lines[0].horizontal_position.proportional, 100.0f / 1920.f, 1);
+ ++n;
+
+ BOOST_REQUIRE_EQUAL(subs[n].lines.size(), 1U);
+ BOOST_CHECK(subs[n].lines[0].horizontal_position.reference == sub::LEFT_OF_SCREEN);
+ BOOST_CHECK_CLOSE(subs[n].lines[0].horizontal_position.proportional, 200.0f / 1920.f, 1);
+ ++n;
+}
+
*/
+
#include "stl_binary_reader.h"
#include "subtitle.h"
#include "test.h"
#include <boost/test/unit_test.hpp>
#include <fstream>
+
using std::ifstream;
+using std::make_shared;
using std::ofstream;
using std::shared_ptr;
-using std::make_shared;
+using std::vector;
+
/* Test reading of a binary STL file */
BOOST_AUTO_TEST_CASE (stl_binary_reader_test1)
}
}
+
+BOOST_AUTO_TEST_CASE(stl_binary_reader_with_colour)
+{
+ auto path = private_test / "at.stl";
+ ifstream in(path.string().c_str());
+ auto reader = make_shared<sub::STLBinaryReader>(in);
+
+ vector<sub::Colour> reference = {
+ { 1, 1, 1 },
+ { 1, 0, 1 },
+ { 1, 1, 1 },
+ { 1, 0, 1 },
+ { 1, 1, 1 },
+ { 1, 1, 0 },
+ { 1, 1, 1 },
+ { 1, 1, 0 },
+ { 1, 1, 1 },
+ { 1, 1, 0 },
+ { 1, 1, 1 },
+ { 1, 1, 0 },
+ { 1, 1, 1 },
+ { 1, 1, 0 }
+ };
+
+ /* Check the first few lines */
+ auto subs = reader->subtitles();
+ BOOST_REQUIRE(subs.size() >= reference.size());
+
+ for (size_t i = 0; i < reference.size(); ++i) {
+ BOOST_CHECK(subs[i].colour == reference[i]);
+ }
+}
+