Support SSA tags in SRT files (DoM #938).
authorCarl Hetherington <cth@carlh.net>
Thu, 13 Feb 2020 23:16:45 +0000 (00:16 +0100)
committerCarl Hetherington <cth@carlh.net>
Thu, 13 Feb 2020 23:25:35 +0000 (00:25 +0100)
src/subrip_reader.cc
src/subrip_reader.h
test/ssa_reader_test.cc
test/subrip_reader_test.cc

index 5e4169906db8922a66493f90bdfcc109415ae3ca..beb81e1c41db1cbaefbbd358a574161128f412a2 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
 #include "util.h"
 #include "sub_assert.h"
 #include "raw_convert.h"
+#include "ssa_reader.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/regex.hpp>
@@ -69,9 +70,6 @@ SubripReader::read (function<optional<string> ()> get_line)
 
        RawSubtitle rs;
 
-       /* This reader extracts no information about where the subtitle
-          should be on screen, so its reference is TOP_OF_SUBTITLE.
-       */
        rs.vertical_position.line = 0;
        rs.vertical_position.reference = TOP_OF_SUBTITLE;
 
@@ -105,6 +103,7 @@ SubripReader::read (function<optional<string> ()> get_line)
                        rs.italic = false;
                        rs.underline = false;
                        rs.vertical_position.line = 0;
+                       rs.vertical_position.reference = TOP_OF_SUBTITLE;
                }
                break;
                case METADATA:
@@ -266,6 +265,8 @@ SubripReader::convert_line (string t, RawSubtitle& p)
                                        SUB_ASSERT (!colours.empty());
                                        colours.pop_back ();
                                        p.colour = colours.back ();
+                               } else if (tag.size() > 0 && tag[0] == '\\') {
+                                       SSAReader::parse_style (p, tag, 288, 288);
                                }
                                tag.clear ();
                                state = TEXT;
index f6586a4e0016af50b38f54b3437611404f57bc61..f45e7c85676ae5ffbd2034ce1a559d4052299a7a 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2019 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
 struct subrip_reader_convert_line_test;
 struct subrip_reader_convert_time_test;
 struct subrip_reader_test5;
+struct subrip_reader_test6;
 
 namespace sub {
 
@@ -44,6 +45,7 @@ private:
        friend struct ::subrip_reader_convert_line_test;
        friend struct ::subrip_reader_convert_time_test;
        friend struct ::subrip_reader_test5;
+       friend struct ::subrip_reader_test6;
        SubripReader () {}
 
        Time convert_time (std::string t);
index 4aa8ff5e28c01fd08009bf9051b2998aad9ee6e3..589ef9238262a7eb1efd919d1459d5a75215b88f 100644 (file)
@@ -227,7 +227,7 @@ BOOST_AUTO_TEST_CASE (ssa_reader_test3)
        /* Alignments */
 
        SUB_START (sub::Time::from_hms (0, 0, 9, 230), sub::Time::from_hms (0, 0, 11, 560));
-       LINE (0, sub::BOTTOM_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::BOTTOM_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
        BLOCK("bottom left", "Arial", 20, false, false, false);
        SUB_END ();
 
@@ -237,12 +237,12 @@ BOOST_AUTO_TEST_CASE (ssa_reader_test3)
        SUB_END ();
 
        SUB_START (sub::Time::from_hms (0, 0, 9, 250), sub::Time::from_hms (0, 0, 11, 560));
-       LINE (0, sub::BOTTOM_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::BOTTOM_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
        BLOCK("bottom right", "Arial", 20, false, false, false);
        SUB_END ();
 
        SUB_START (sub::Time::from_hms (0, 0, 9, 260), sub::Time::from_hms (0, 0, 11, 560));
-       LINE (0, sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
        BLOCK("middle left", "Arial", 20, false, false, false);
        SUB_END ();
 
@@ -252,12 +252,12 @@ BOOST_AUTO_TEST_CASE (ssa_reader_test3)
        SUB_END ();
 
        SUB_START (sub::Time::from_hms (0, 0, 9, 280), sub::Time::from_hms (0, 0, 11, 560));
-       LINE (0, sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::VERTICAL_CENTRE_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
        BLOCK("middle right", "Arial", 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 (0, sub::TOP_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::TOP_OF_SCREEN, 0, sub::LEFT_OF_SCREEN);
        BLOCK("top left", "Arial", 20, false, false, false);
        SUB_END ();
 
@@ -267,7 +267,7 @@ BOOST_AUTO_TEST_CASE (ssa_reader_test3)
        SUB_END ();
 
        SUB_START (sub::Time::from_hms (0, 0, 9, 310), sub::Time::from_hms (0, 0, 11, 560));
-       LINE (0, sub::TOP_OF_SCREEN, 0, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       LINE (0, sub::TOP_OF_SCREEN, 0, sub::RIGHT_OF_SCREEN);
        BLOCK("top right", "Arial", 20, false, false, false);
        SUB_END ();
 
index affdd7574846bd93a755f07013b244c5e969bb34..87f7b51477f5b5edc4b0696a79f6e0f0770083f3 100644 (file)
@@ -1,5 +1,5 @@
 /*
-    Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
+    Copyright (C) 2014-2020 Carl Hetherington <cth@carlh.net>
 
     This program is free software; you can redistribute it and/or modify
     it under the terms of the GNU General Public License as published by
@@ -61,6 +61,7 @@ BOOST_AUTO_TEST_CASE (subrip_reader_test)
        BOOST_CHECK_EQUAL (b.bold, false);
        BOOST_CHECK_EQUAL (b.italic, false);
        BOOST_CHECK_EQUAL (b.underline, false);
+       BOOST_REQUIRE (j->vertical_position.line);
        BOOST_CHECK_EQUAL (j->vertical_position.line.get(), 0);
        BOOST_CHECK_EQUAL (j->vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
        ++j;
@@ -75,6 +76,7 @@ BOOST_AUTO_TEST_CASE (subrip_reader_test)
        BOOST_CHECK_EQUAL (b.bold, false);
        BOOST_CHECK_EQUAL (b.italic, false);
        BOOST_CHECK_EQUAL (b.underline, false);
+       BOOST_REQUIRE (j->vertical_position.line);
        BOOST_CHECK_EQUAL (j->vertical_position.line.get(), 1);
        BOOST_CHECK_EQUAL (j->vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
        ++i;
@@ -563,3 +565,59 @@ BOOST_AUTO_TEST_CASE (subrip_reader_test5)
        BOOST_CHECK_CLOSE (r._subs.front().colour.g, 2.0 / 255, 0.1);
        BOOST_CHECK_CLOSE (r._subs.front().colour.b, 3.0 / 255, 0.1);
 }
+
+/** Test alignment */
+BOOST_AUTO_TEST_CASE (subrip_reader_test6)
+{
+       sub::RawSubtitle rs;
+       rs.vertical_position.line = 0;
+       rs.vertical_position.reference = sub::TOP_OF_SUBTITLE;
+       sub::SubripReader r;
+       r.convert_line ("Hello world", rs);
+       BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
+       BOOST_CHECK_EQUAL (r._subs.front().text, "Hello world");
+       BOOST_REQUIRE (r._subs.front().vertical_position.line);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
+       BOOST_REQUIRE (r._subs.front().vertical_position.reference);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::TOP_OF_SUBTITLE);
+       r._subs.clear ();
+
+       rs = sub::RawSubtitle ();
+       rs.vertical_position.line = 0;
+       r.convert_line ("{\\an1}Hello", rs);
+       BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
+       BOOST_CHECK_EQUAL (r._subs.front().text, "Hello");
+       BOOST_REQUIRE (r._subs.front().vertical_position.line);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
+       BOOST_REQUIRE (r._subs.front().vertical_position.reference);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::LEFT_OF_SCREEN);
+       r._subs.clear ();
+
+       rs = sub::RawSubtitle ();
+       rs.vertical_position.line = 0;
+       r.convert_line ("{\\an2}to", rs);
+       BOOST_REQUIRE_EQUAL (r._subs.size(), 1);
+       BOOST_CHECK_EQUAL (r._subs.front().text, "to");
+       BOOST_REQUIRE (r._subs.front().vertical_position.line);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
+       BOOST_REQUIRE (r._subs.front().vertical_position.reference);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::HORIZONTAL_CENTRE_OF_SCREEN);
+       r._subs.clear ();
+
+       rs = sub::RawSubtitle ();
+       rs.vertical_position.line = 0;
+       r.convert_line ("{\\an3}you", rs);
+       BOOST_CHECK_EQUAL (r._subs.front().text, "you");
+       BOOST_REQUIRE (r._subs.front().vertical_position.line);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.line.get(), 0);
+       BOOST_REQUIRE (r._subs.front().vertical_position.reference);
+       BOOST_CHECK_EQUAL (r._subs.front().vertical_position.reference.get(), sub::BOTTOM_OF_SCREEN);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.proportional, 0);
+       BOOST_CHECK_EQUAL (r._subs.front().horizontal_position.reference, sub::RIGHT_OF_SCREEN);
+       r._subs.clear ();
+}
+