2 Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 #include "subrip_reader.h"
23 #include "exceptions.h"
25 #include <boost/test/unit_test.hpp>
26 #include <boost/filesystem.hpp>
35 /* Test reading of a Subrip file */
36 BOOST_AUTO_TEST_CASE (subrip_reader_test)
38 FILE* f = fopen ("test/data/test.srt", "r");
39 sub::SubripReader reader (f);
41 auto subs = sub::collect<std::vector<sub::Subtitle>> (reader.subtitles());
43 auto i = subs.begin ();
48 BOOST_CHECK (i != subs.end ());
49 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 0, 41, 90));
50 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 0, 42, 210));
52 auto j = i->lines.begin();
53 BOOST_CHECK (j != i->lines.end ());
54 BOOST_CHECK_EQUAL (j->blocks.size(), 1);
55 auto b = j->blocks.front();
56 BOOST_CHECK_EQUAL (b.text, "This is a subtitle");
57 /* No font is specified by subrip, so none should be seen here */
58 BOOST_CHECK (!b.font);
59 BOOST_CHECK (!b.font_size.specified());
60 BOOST_CHECK_EQUAL (b.bold, false);
61 BOOST_CHECK_EQUAL (b.italic, false);
62 BOOST_CHECK_EQUAL (b.underline, false);
63 BOOST_REQUIRE (j->vertical_position.line);
64 BOOST_CHECK_EQUAL (j->vertical_position.line.get(), 0);
65 BOOST_CHECK_EQUAL (j->vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
68 BOOST_CHECK (j != i->lines.end ());
69 BOOST_CHECK_EQUAL (j->blocks.size(), 1);
70 b = j->blocks.front ();
71 BOOST_CHECK_EQUAL (b.text, "and that's a line break");
72 /* No font is specified by subrip, so none should be seen here */
73 BOOST_CHECK (!b.font);
74 BOOST_CHECK (!b.font_size.specified());
75 BOOST_CHECK_EQUAL (b.bold, false);
76 BOOST_CHECK_EQUAL (b.italic, false);
77 BOOST_CHECK_EQUAL (b.underline, false);
78 BOOST_REQUIRE (j->vertical_position.line);
79 BOOST_CHECK_EQUAL (j->vertical_position.line.get(), 1);
80 BOOST_CHECK_EQUAL (j->vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
86 BOOST_CHECK (i != subs.end ());
87 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 1, 1, 10));
88 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 1, 2, 100));
90 BOOST_CHECK_EQUAL (i->lines.size(), 1);
91 sub::Line l = i->lines.front ();
92 BOOST_CHECK_EQUAL (l.blocks.size(), 7);
93 BOOST_CHECK_EQUAL (l.vertical_position.line.get(), 0);
94 BOOST_CHECK_EQUAL (l.vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
96 auto k = l.blocks.begin();
98 BOOST_CHECK (k != l.blocks.end ());
99 BOOST_CHECK_EQUAL (k->text, "This is some ");
100 /* No font is specified by subrip, so none should be seen here */
101 BOOST_CHECK (!b.font);
102 BOOST_CHECK (!b.font_size.specified());
103 BOOST_CHECK_EQUAL (k->bold, false);
104 BOOST_CHECK_EQUAL (k->italic, false);
105 BOOST_CHECK_EQUAL (k->underline, false);
108 BOOST_CHECK (k != l.blocks.end ());
109 BOOST_CHECK_EQUAL (k->text, "bold");
110 /* No font is specified by subrip, so none should be seen here */
111 BOOST_CHECK (!b.font);
112 BOOST_CHECK (!b.font_size.specified());
113 BOOST_CHECK_EQUAL (k->bold, true);
114 BOOST_CHECK_EQUAL (k->italic, false);
115 BOOST_CHECK_EQUAL (k->underline, false);
118 BOOST_CHECK (k != l.blocks.end ());
119 BOOST_CHECK_EQUAL (k->text, " and some ");
120 /* No font is specified by subrip, so none should be seen here */
121 BOOST_CHECK (!b.font);
122 BOOST_CHECK (!b.font_size.specified());
123 BOOST_CHECK_EQUAL (k->bold, false);
124 BOOST_CHECK_EQUAL (k->italic, false);
125 BOOST_CHECK_EQUAL (k->underline, false);
128 BOOST_CHECK (k != l.blocks.end ());
129 BOOST_CHECK_EQUAL (k->text, "bold italic");
130 /* No font is specified by subrip, so none should be seen here */
131 BOOST_CHECK (!b.font);
132 BOOST_CHECK (!b.font_size.specified());
133 BOOST_CHECK_EQUAL (k->bold, true);
134 BOOST_CHECK_EQUAL (k->italic, true);
135 BOOST_CHECK_EQUAL (k->underline, false);
138 BOOST_CHECK (k != l.blocks.end ());
139 BOOST_CHECK_EQUAL (k->text, " and some ");
140 /* No font is specified by subrip, so none should be seen here */
141 BOOST_CHECK (!b.font);
142 BOOST_CHECK (!b.font_size.specified());
143 BOOST_CHECK_EQUAL (k->bold, false);
144 BOOST_CHECK_EQUAL (k->italic, false);
145 BOOST_CHECK_EQUAL (k->underline, false);
148 BOOST_CHECK (k != l.blocks.end ());
149 BOOST_CHECK_EQUAL (k->text, "underlined");
150 /* No font is specified by subrip, so none should be seen here */
151 BOOST_CHECK (!b.font);
152 BOOST_CHECK (!b.font_size.specified());
153 BOOST_CHECK_EQUAL (k->bold, false);
154 BOOST_CHECK_EQUAL (k->italic, false);
155 BOOST_CHECK_EQUAL (k->underline, true);
158 BOOST_CHECK (k != l.blocks.end ());
159 BOOST_CHECK_EQUAL (k->text, ".");
160 /* No font is specified by subrip, so none should be seen here */
161 BOOST_CHECK (!b.font);
162 BOOST_CHECK (!b.font_size.specified());
163 BOOST_CHECK_EQUAL (k->bold, false);
164 BOOST_CHECK_EQUAL (k->italic, false);
165 BOOST_CHECK_EQUAL (k->underline, false);
168 BOOST_CHECK (k == l.blocks.end ());
171 /* Test reading of another Subrip file */
172 BOOST_AUTO_TEST_CASE (subrip_reader_test2)
174 FILE* f = fopen ("test/data/test2.srt", "r");
175 sub::SubripReader reader (f);
177 auto subs = sub::collect<vector<sub::Subtitle>> (reader.subtitles());
179 auto i = subs.begin();
181 BOOST_CHECK (i != subs.end ());
182 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 1, 49, 200));
183 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 1, 52, 351));
184 BOOST_CHECK_EQUAL (i->lines.size(), 2);
185 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "This is a subtitle, and it goes ");
186 BOOST_CHECK_EQUAL (i->lines.back().blocks.front().text, "over two lines.");
189 BOOST_CHECK (i != subs.end ());
190 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 1, 52, 440));
191 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 1, 54, 351));
192 BOOST_CHECK_EQUAL (i->lines.size(), 1);
193 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "We have emboldened this");
194 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().bold, true);
197 BOOST_CHECK (i != subs.end ());
198 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 1, 54, 440));
199 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 1, 56, 590));
200 BOOST_CHECK_EQUAL (i->lines.size(), 1);
201 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "And italicised this.");
202 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().italic, true);
205 BOOST_CHECK (i != subs.end ());
206 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 1, 56, 680));
207 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 1, 58, 955));
208 BOOST_CHECK_EQUAL (i->lines.size(), 1);
209 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "Shall I compare thee to a summers' day?");
212 BOOST_CHECK (i != subs.end ());
213 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 2, 0, 840));
214 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 2, 3, 400));
215 BOOST_CHECK_EQUAL (i->lines.size(), 1);
216 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "Is this a dagger I see before me?");
219 BOOST_CHECK (i != subs.end ());
220 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 3, 54, 560));
221 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 3, 56, 471));
222 BOOST_CHECK_EQUAL (i->lines.size(), 1);
223 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "Hello world.");
226 BOOST_CHECK (i != subs.end ());
227 BOOST_CHECK_EQUAL (i->from, sub::Time::from_hms (0, 4, 50, 123));
228 BOOST_CHECK_EQUAL (i->to, sub::Time::from_hms (0, 4, 55, 23));
229 BOOST_CHECK_EQUAL (i->lines.size(), 2);
230 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().text, "Some italics over");
231 BOOST_CHECK_EQUAL (i->lines.front().blocks.front().italic, true);
232 BOOST_CHECK_EQUAL (i->lines.back().blocks.front().text, "multiple lines");
233 BOOST_CHECK_EQUAL (i->lines.back().blocks.front().italic, true);
236 BOOST_CHECK (i == subs.end ());
239 /** Test SubripReader::convert_line */
240 BOOST_AUTO_TEST_CASE (subrip_reader_convert_line_test)
245 r.convert_line ("Hello world", rs);
246 BOOST_CHECK_EQUAL (r._subs.size(), 1);
247 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
250 rs = sub::RawSubtitle();
251 r.convert_line ("<b>Hello world</b>", rs);
252 BOOST_CHECK_EQUAL (r._subs.size(), 1);
253 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
254 BOOST_CHECK_EQUAL (r._subs.front().bold, true);
257 rs = sub::RawSubtitle();
258 r.convert_line ("<i>Hello world</i>", rs);
259 BOOST_CHECK_EQUAL (r._subs.size(), 1);
260 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
261 BOOST_CHECK_EQUAL (r._subs.front().italic, true);
264 rs = sub::RawSubtitle();
265 r.convert_line ("<u>Hello world</u>", rs);
266 BOOST_CHECK_EQUAL (r._subs.size(), 1);
267 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
268 BOOST_CHECK_EQUAL (r._subs.front().underline, true);
271 rs = sub::RawSubtitle();
272 r.convert_line ("{b}Hello world{/b}", rs);
273 BOOST_CHECK_EQUAL (r._subs.size(), 1);
274 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
275 BOOST_CHECK_EQUAL (r._subs.front().bold, true);
278 rs = sub::RawSubtitle();
279 r.convert_line ("{i}Hello world{/i}", rs);
280 BOOST_CHECK_EQUAL (r._subs.size(), 1);
281 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
282 BOOST_CHECK_EQUAL (r._subs.front().italic, true);
285 rs = sub::RawSubtitle();
286 r.convert_line ("{u}Hello world{/u}", rs);
287 BOOST_CHECK_EQUAL (r._subs.size(), 1);
288 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
289 BOOST_CHECK_EQUAL (r._subs.front().underline, true);
292 rs = sub::RawSubtitle();
293 r.convert_line ("<b>This is <i>nesting</i> of subtitles</b>", rs);
294 BOOST_CHECK_EQUAL (r._subs.size(), 3);
295 auto i = r._subs.begin();
296 BOOST_CHECK_EQUAL (i->text, "This is ");
297 BOOST_CHECK_EQUAL (i->bold, true);
298 BOOST_CHECK_EQUAL (i->italic, false);
300 BOOST_CHECK_EQUAL (i->text, "nesting");
301 BOOST_CHECK_EQUAL (i->bold, true);
302 BOOST_CHECK_EQUAL (i->italic, true);
304 BOOST_CHECK_EQUAL (i->text, " of subtitles");
305 BOOST_CHECK_EQUAL (i->bold, true);
306 BOOST_CHECK_EQUAL (i->italic, false);
310 rs = sub::RawSubtitle();
311 r.convert_line ("<B>This is <I>nesting</I> of subtitles</B>", rs);
312 BOOST_CHECK_EQUAL (r._subs.size(), 3);
314 BOOST_CHECK_EQUAL (i->text, "This is ");
315 BOOST_CHECK_EQUAL (i->bold, true);
316 BOOST_CHECK_EQUAL (i->italic, false);
318 BOOST_CHECK_EQUAL (i->text, "nesting");
319 BOOST_CHECK_EQUAL (i->bold, true);
320 BOOST_CHECK_EQUAL (i->italic, true);
322 BOOST_CHECK_EQUAL (i->text, " of subtitles");
323 BOOST_CHECK_EQUAL (i->bold, true);
324 BOOST_CHECK_EQUAL (i->italic, false);
328 rs = sub::RawSubtitle();
329 r.convert_line ("<font color=\"#ff00ff\">simple color</font>", rs);
330 BOOST_CHECK_EQUAL (r._subs.size(), 1);
331 BOOST_CHECK_EQUAL (r._subs.front().text, "simple color");
332 BOOST_CHECK_EQUAL (r._subs.front().bold, false);
333 BOOST_CHECK_CLOSE (r._subs.front().colour.r, 1, 0.1);
334 BOOST_CHECK (fabs (r._subs.front().colour.g) < 0.01);
335 BOOST_CHECK_CLOSE (r._subs.front().colour.b, 1, 0.1);
338 /* single quotes are apparently also allowed */
339 rs = sub::RawSubtitle();
340 r.convert_line("<font color=\'#ff00ff\'>simple color</font>", rs);
341 BOOST_CHECK_EQUAL(r._subs.size(), 1);
342 BOOST_CHECK_EQUAL(r._subs.front().text, "simple color");
343 BOOST_CHECK_EQUAL(r._subs.front().bold, false);
344 BOOST_CHECK_CLOSE(r._subs.front().colour.r, 1, 0.1);
345 BOOST_CHECK(fabs(r._subs.front().colour.g) < 0.01);
346 BOOST_CHECK_CLOSE(r._subs.front().colour.b, 1, 0.1);
349 rs = sub::RawSubtitle();
350 r.convert_line ("<font color=\"#FF00FF\">simple color in capitals</font>", rs);
351 BOOST_CHECK_EQUAL (r._subs.size(), 1);
352 BOOST_CHECK_EQUAL (r._subs.front().text, "simple color in capitals");
353 BOOST_CHECK_EQUAL (r._subs.front().bold, false);
354 BOOST_CHECK_CLOSE (r._subs.front().colour.r, 1, 0.1);
355 BOOST_CHECK (fabs (r._subs.front().colour.g) < 0.01);
356 BOOST_CHECK_CLOSE (r._subs.front().colour.b, 1, 0.1);
359 rs = sub::RawSubtitle();
360 r.convert_line ("<font color=\"#ff0000\">some red text <b>in bold</b></font>", rs);
361 BOOST_CHECK_EQUAL (r._subs.size(), 2);
362 i = r._subs.begin ();
363 BOOST_CHECK_EQUAL (i->text, "some red text ");
364 BOOST_CHECK_EQUAL (i->bold, false);
365 BOOST_CHECK_CLOSE (i->colour.r, 1, 0.1);
366 BOOST_CHECK (fabs (i->colour.g) < 0.01);
367 BOOST_CHECK (fabs (i->colour.b) < 0.01);
369 BOOST_CHECK_EQUAL (i->text, "in bold");
370 BOOST_CHECK_EQUAL (i->bold, true);
371 BOOST_CHECK_CLOSE (i->colour.r, 1, 0.1);
372 BOOST_CHECK (fabs (i->colour.g) < 0.01);
373 BOOST_CHECK (fabs (i->colour.b) < 0.01);
376 rs = sub::RawSubtitle();
377 r.convert_line ("<Font color=\"#ff0000\">some red text <b>in bold</b></font>", rs);
378 BOOST_CHECK_EQUAL (r._subs.size(), 2);
379 i = r._subs.begin ();
380 BOOST_CHECK_EQUAL (i->text, "some red text ");
381 BOOST_CHECK_EQUAL (i->bold, false);
382 BOOST_CHECK_CLOSE (i->colour.r, 1, 0.1);
383 BOOST_CHECK (fabs (i->colour.g) < 0.01);
384 BOOST_CHECK (fabs (i->colour.b) < 0.01);
386 BOOST_CHECK_EQUAL (i->text, "in bold");
387 BOOST_CHECK_EQUAL (i->bold, true);
388 BOOST_CHECK_CLOSE (i->colour.r, 1, 0.1);
389 BOOST_CHECK (fabs (i->colour.g) < 0.01);
390 BOOST_CHECK (fabs (i->colour.b) < 0.01);
393 rs = sub::RawSubtitle();
394 r.convert_line ("<font color=\"#0000ff\">some blue text <b>in bold</b></font>", rs);
395 BOOST_CHECK_EQUAL (r._subs.size(), 2);
396 i = r._subs.begin ();
397 BOOST_CHECK_EQUAL (i->text, "some blue text ");
398 BOOST_CHECK_EQUAL (i->bold, false);
399 BOOST_CHECK (fabs (i->colour.r) < 0.01);
400 BOOST_CHECK (fabs (i->colour.g) < 0.01);
401 BOOST_CHECK_CLOSE (i->colour.b, 1, 0.1);
403 BOOST_CHECK_EQUAL (i->text, "in bold");
404 BOOST_CHECK_EQUAL (i->bold, true);
405 BOOST_CHECK (fabs (i->colour.r) < 0.01);
406 BOOST_CHECK (fabs (i->colour.g) < 0.01);
407 BOOST_CHECK_CLOSE (i->colour.b, 1, 0.1);
410 rs = sub::RawSubtitle();
411 r.convert_line("<font color=\"#0000ffdd\">some blue text with alpha</font>", rs);
412 BOOST_CHECK_EQUAL(r._subs.size(), 1);
414 BOOST_CHECK_EQUAL(i->text, "some blue text with alpha");
415 BOOST_CHECK_EQUAL(i->bold, false);
416 BOOST_CHECK(fabs(i->colour.r) < 0.01);
417 BOOST_CHECK(fabs(i->colour.g) < 0.01);
418 BOOST_CHECK_CLOSE(i->colour.b, 1, 0.1);
421 rs = sub::RawSubtitle();
422 r.convert_line ("<< angle brackets but no HTML >>", rs);
423 BOOST_CHECK_EQUAL (r._subs.size(), 1);
424 i = r._subs.begin ();
425 BOOST_CHECK_EQUAL (i->text, "<< angle brackets but no HTML >>");
429 /** Test SubripReader::convert_time */
430 BOOST_AUTO_TEST_CASE (subrip_reader_convert_time_test)
432 sub::SubripReader reader;
433 auto t = reader.convert_time("00:03:10,500", ",");
435 BOOST_CHECK_EQUAL(*t, sub::Time::from_hms(0, 3, 10, 500));
436 t = reader.convert_time("04:19:51,782", ",");
438 BOOST_CHECK_EQUAL(*t, sub::Time::from_hms(4, 19, 51, 782));
442 test (boost::filesystem::path p)
444 p = private_test / p;
445 FILE* f = fopen (p.string().c_str(), "r");
448 cerr << p << " not found.\n";
451 sub::SubripReader r (f);
456 test_throw (boost::filesystem::path p)
458 p = private_test / p;
459 FILE* f = fopen (p.string().c_str(), "r");
462 cerr << p << " not found.\n";
465 BOOST_CHECK_THROW (sub::SubripReader r(f), sub::SubripError);
469 /** Test of reading some typical .srt files */
470 BOOST_AUTO_TEST_CASE (subrip_read_test)
472 test ("sintel_en.srt");
473 test ("sintel_fr.srt");
476 test ("Subtitulos_H_eng.srt");
478 test_throw ("subtitulo1.srt");
481 #define SUB_START(f, t) \
482 BOOST_REQUIRE (i != subs.end ()); \
483 BOOST_CHECK_EQUAL (i->from, f); \
484 BOOST_CHECK_EQUAL (i->to, t); \
485 j = i->lines.begin ();
488 BOOST_REQUIRE (j != i->lines.end ()); \
489 BOOST_CHECK (j->vertical_position.line); \
490 BOOST_CHECK_EQUAL (j->vertical_position.line.get(), p); \
491 BOOST_CHECK (j->vertical_position.reference); \
492 BOOST_CHECK_EQUAL (j->vertical_position.reference.get(), sub::TOP_OF_SUBTITLE); \
493 k = j->blocks.begin (); \
496 #define BLOCK(t, f, s, b, i, u) \
497 BOOST_REQUIRE (k != j->blocks.end ()); \
498 BOOST_CHECK_EQUAL (k->text, t); \
499 BOOST_CHECK_EQUAL (k->bold, b); \
500 BOOST_CHECK_EQUAL (k->italic, i); \
501 BOOST_CHECK_EQUAL (k->underline, u); \
507 /** Test reading of another .srt file */
508 BOOST_AUTO_TEST_CASE (subrip_reader_test3)
510 boost::filesystem::path p = private_test / "DCP-o-matic_test_subs_1.srt";
511 FILE* f = fopen (p.string().c_str(), "r");
512 sub::SubripReader reader (f);
514 auto subs = sub::collect<std::vector<sub::Subtitle>> (reader.subtitles());
516 auto i = subs.begin ();
517 vector<sub::Line>::iterator j;
518 vector<sub::Block>::iterator k;
520 BOOST_REQUIRE (i != subs.end ());
522 SUB_START (sub::Time::from_hms (0, 0, 0, 76), sub::Time::from_hms (0, 0, 1, 116));
524 BLOCK ("This line is normal", "Arial", 30, false, false, false);
526 BLOCK ("This line is bold", "Arial", 30, true, false, false);
529 SUB_START (sub::Time::from_hms (0, 0, 1, 206), sub::Time::from_hms (0, 0, 2, 246));
531 BLOCK ("This line is bold", "Arial", 30, true, false, false);
533 BLOCK ("This line is normal", "Arial", 30, false, false, false);
536 SUB_START (sub::Time::from_hms (0, 0, 2, 308), sub::Time::from_hms (0, 0, 3, 380));
538 BLOCK ("This line is bold", "Arial", 30, true, false, false);
540 BLOCK ("This line is italic", "Arial", 30, false, true, false);
543 SUB_START (sub::Time::from_hms (0, 0, 3, 404), sub::Time::from_hms (0, 0, 4, 484));
545 BLOCK ("This line is italic", "Arial", 30, false, true, false);
547 BLOCK ("This line is bold", "Arial", 30, true, false, false);
550 SUB_START (sub::Time::from_hms (0, 0, 4, 519), sub::Time::from_hms (0, 0, 5, 604));
552 BLOCK ("Last three words are ", "Arial", 30, false, false, false);
553 BLOCK ("bold AND italic", "Arial", 30, true, true, false);
555 BLOCK ("Last three words are ", "Arial", 30, false, false, false);
556 BLOCK ("italic AND bold", "Arial", 30, true, true, false);
559 SUB_START (sub::Time::from_hms (0, 0, 5, 628), sub::Time::from_hms (0, 0, 6, 712));
561 BLOCK ("Last three words are ", "Arial", 30, false, false, false);
562 BLOCK ("bold AND italic", "Arial", 30, true, true, false);
564 BLOCK ("First three words", "Arial", 30, true, true, false);
565 BLOCK (" are italic AND bold", "Arial", 30, false, false, false);
568 SUB_START (sub::Time::from_hms (0, 0, 6, 736), sub::Time::from_hms (0, 0, 8, 31));
570 BLOCK ("Last three words are ", "Arial", 30, false, false, false);
571 BLOCK ("bold AND italic", "Arial", 30, true, true, false);
573 BLOCK ("This line is normal", "Arial", 30, false, false, false);
576 SUB_START (sub::Time::from_hms (0, 0, 8, 94), sub::Time::from_hms (0, 0, 9, 211));
578 BLOCK ("Both lines are bold AND italic", "Arial", 30, true, true, false);
580 BLOCK ("Both lines are bold AND italic", "Arial", 30, true, true, false);
584 /** Test reading of a .srt file with RTL text */
585 BOOST_AUTO_TEST_CASE (subrip_reader_test4)
587 boost::filesystem::path p = private_test / "rtl.srt";
588 FILE* f = fopen (p.string().c_str(), "r");
589 sub::SubripReader reader (f);
591 auto subs = sub::collect<std::vector<sub::Subtitle>>(reader.subtitles());
593 auto i = subs.begin();
594 std::cout << i->lines.front().blocks.front().text << "\n";
596 std::string const t = i->lines.front().blocks.front().text;
597 for (size_t i = 0; i < t.length() - 2; ++i) {
598 /* Check that unicode U+202B (right-to-left embedding) has been stripped */
599 unsigned char const a = t[i];
600 unsigned char const b = t[i+1];
601 unsigned char const c = t[i+2];
602 BOOST_CHECK ((a != 0xe2 || b != 0x80 || c != 0xab));
605 BOOST_CHECK (t == "- \"(دريه فابينار)\"");
608 /** Test <font color="rgba(255,255,255,255)"> */
609 BOOST_AUTO_TEST_CASE (subrip_reader_test5)
613 r.convert_line ("<font color=\"rgba(255,128,64,15)\">Foo bar</font>", rs);
614 BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
615 BOOST_CHECK_EQUAL (r._subs.front().text, "Foo bar");
616 BOOST_CHECK_CLOSE (r._subs.front().colour.r, 255.0 / 255, 0.1);
617 BOOST_CHECK_CLOSE (r._subs.front().colour.g, 128.0 / 255, 0.1);
618 BOOST_CHECK_CLOSE (r._subs.front().colour.b, 64.0 / 255, 0.1);
621 rs = sub::RawSubtitle ();
622 r.convert_line ("<font color=\"rgba(1, 2 , 3, 4)\">Foo bar</font>", rs);
623 BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
624 BOOST_CHECK_EQUAL (r._subs.front().text, "Foo bar");
625 BOOST_CHECK_CLOSE (r._subs.front().colour.r, 1.0 / 255, 0.1);
626 BOOST_CHECK_CLOSE (r._subs.front().colour.g, 2.0 / 255, 0.1);
627 BOOST_CHECK_CLOSE (r._subs.front().colour.b, 3.0 / 255, 0.1);
631 /** Test alignment */
632 BOOST_AUTO_TEST_CASE (subrip_reader_test6)
635 rs.vertical_position.line = 0;
636 rs.vertical_position.reference = sub::TOP_OF_SUBTITLE;
638 r.convert_line ("Hello world", rs);
639 BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
640 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
641 BOOST_REQUIRE (r._subs.front().vertical_position.line);
642 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
643 BOOST_REQUIRE (r._subs.front().vertical_position.reference);
644 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
647 rs = sub::RawSubtitle ();
648 rs.vertical_position.line = 0;
649 r.convert_line ("{\\an1}Hello", rs);
650 BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
651 BOOST_CHECK_EQUAL (r._subs.front().text, "Hello");
652 BOOST_REQUIRE (r._subs.front().vertical_position.line);
653 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
654 BOOST_REQUIRE (r._subs.front().vertical_position.reference);
655 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
656 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
657 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::LEFT_OF_SCREEN);
660 rs = sub::RawSubtitle ();
661 rs.vertical_position.line = 0;
662 r.convert_line ("{\\an2}to", rs);
663 BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
664 BOOST_CHECK_EQUAL (r._subs.front().text, "to");
665 BOOST_REQUIRE (r._subs.front().vertical_position.line);
666 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
667 BOOST_REQUIRE (r._subs.front().vertical_position.reference);
668 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
669 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
670 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::HORIZONTAL_CENTRE_OF_SCREEN);
673 rs = sub::RawSubtitle ();
674 rs.vertical_position.line = 0;
675 r.convert_line ("{\\an3}you", rs);
676 BOOST_CHECK_EQUAL (r._subs.front().text, "you");
677 BOOST_REQUIRE (r._subs.front().vertical_position.line);
678 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
679 BOOST_REQUIRE (r._subs.front().vertical_position.reference);
680 BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
681 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
682 BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::RIGHT_OF_SCREEN);
687 BOOST_AUTO_TEST_CASE(subrip_with_unicode_line_separator_test)
689 auto f = fopen ("test/data/newline.srt", "r");
691 sub::SubripReader reader(f);
693 auto subs = sub::collect<std::vector<sub::Subtitle>>(reader.subtitles());
695 BOOST_REQUIRE_EQUAL(subs.size(), 2U);
697 BOOST_REQUIRE_EQUAL(subs[0].lines.size(), 2U);
698 BOOST_REQUIRE_EQUAL(subs[0].lines[0].blocks.size(), 1U);
699 BOOST_CHECK_EQUAL(subs[0].lines[0].blocks[0].text, "Du fühlst dich danach besser.");
700 BOOST_REQUIRE_EQUAL(subs[0].lines[1].blocks.size(), 1U);
701 BOOST_CHECK_EQUAL(subs[0].lines[1].blocks[0].text, "Okay, Kleiner?");
703 BOOST_REQUIRE_EQUAL(subs[1].lines.size(), 2U);
704 BOOST_REQUIRE_EQUAL(subs[1].lines[0].blocks.size(), 1U);
705 BOOST_CHECK_EQUAL(subs[1].lines[0].blocks[0].text, "Sie kann es nicht machen");
706 BOOST_REQUIRE_EQUAL(subs[1].lines[1].blocks.size(), 1U);
707 BOOST_CHECK_EQUAL(subs[1].lines[1].blocks[0].text, "wenn du dich bewegst.");