summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2026-06-28 15:37:54 +0200
committerCarl Hetherington <cth@carlh.net>2026-06-28 15:37:54 +0200
commit679d076c4d353b489bc4b9fe56c67937b8013c63 (patch)
tree53c8eeeb2ecba9c1b38fcfe37af404d2338f6592
parent8626b10f3b3ca009fa13226ae299c7333b951b56 (diff)
Sort lines before writing subrip.HEADv1.6.62main
Otherwise the vertical position of the lines might not be properly respected.
-rw-r--r--src/subrip_writer.cc5
-rw-r--r--test/subrip_writer_test.cc43
2 files changed, 47 insertions, 1 deletions
diff --git a/src/subrip_writer.cc b/src/subrip_writer.cc
index 80602d0..ac42ff3 100644
--- a/src/subrip_writer.cc
+++ b/src/subrip_writer.cc
@@ -21,6 +21,7 @@
#include "subrip_writer.h"
#include "subtitle.h"
#include <fmt/format.h>
+#include <algorithm>
#include <fstream>
@@ -62,7 +63,9 @@ sub::write_subrip(vector<Subtitle> const& subtitles, boost::filesystem::path fil
f << index << "\n";
f << time_to_subrip_string(sub.from) << " --> " << time_to_subrip_string(sub.to) << "\n";
- for (auto const& line: sub.lines) {
+ auto sorted_lines = sub.lines;
+ std::sort(sorted_lines.begin(), sorted_lines.end(), [](Line const& a, Line const& b) { return a.vertical_position < b.vertical_position; });
+ for (auto const& line: sorted_lines) {
for (auto const& block: line.blocks) {
f << wrap_with_tags(block.text, block.bold, block.italic, block.underline);
}
diff --git a/test/subrip_writer_test.cc b/test/subrip_writer_test.cc
index 2303056..74edee2 100644
--- a/test/subrip_writer_test.cc
+++ b/test/subrip_writer_test.cc
@@ -17,8 +17,10 @@
*/
+#include "collect.h"
#include "subrip_writer.h"
#include "subtitle.h"
+#include "test.h"
#include <boost/test/unit_test.hpp>
#include <fstream>
@@ -99,3 +101,44 @@ BOOST_AUTO_TEST_CASE(subrip_writer_test)
BOOST_CHECK_EQUAL(lines[6], "00:01:01,010 --> 00:01:02,100");
BOOST_CHECK_EQUAL(lines[7], "This is some <b>bold</b> and some <u>underlined</u>");
}
+
+
+BOOST_AUTO_TEST_CASE(subrip_writer_handles_out_of_order_vertical_position)
+{
+ vector<sub::RawSubtitle> raw;
+
+ {
+ sub::RawSubtitle sub;
+ sub.text = "This goes underneath";
+ sub.vertical_position.reference = sub::VerticalReference::TOP_OF_SCREEN;
+ sub.vertical_position.proportional = 0.75;
+ sub.from = sub::Time::from_hmsf(0, 0, 0, 0, sub::Rational{24, 1});
+ sub.to = sub::Time::from_hmsf(0, 0, 5, 0, sub::Rational{24, 1});
+ raw.push_back(sub);
+ }
+
+ {
+ sub::RawSubtitle sub;
+ sub.text = "This goes on top";
+ sub.vertical_position.reference = sub::VerticalReference::TOP_OF_SCREEN;
+ sub.vertical_position.proportional = 0.5;
+ sub.from = sub::Time::from_hmsf(0, 0, 0, 0, sub::Rational{24, 1});
+ sub.to = sub::Time::from_hmsf(0, 0, 5, 0, sub::Rational{24, 1});
+ raw.push_back(sub);
+ }
+
+ auto subs = sub::collect<std::vector<sub::Subtitle>>(raw);
+ boost::filesystem::path srt = "build/test/test_subrip_writer.srt";
+ sub::write_subrip(subs, srt);
+
+ auto lines = read_lines(srt);
+
+ BOOST_REQUIRE_EQUAL(lines.size(), 5U);
+ BOOST_CHECK_EQUAL(lines[0], "1");
+ BOOST_CHECK_EQUAL(lines[1], "00:00:00,000 --> 00:00:05,000");
+ BOOST_CHECK_EQUAL(lines[2], "This goes on top");
+ BOOST_CHECK_EQUAL(lines[3], "This goes underneath");
+ BOOST_CHECK_EQUAL(lines[4], "");
+
+}
+