diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-12-28 01:21:20 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-12-30 12:22:30 +0100 |
| commit | 0beaf6245ef0c1462cbe7eaf6faeabb651b68de3 (patch) | |
| tree | d35f286cf671082ca501a4a8184ebbd9e6c33285 | |
| parent | 931aa567b5435ae15877547b6030a583e1b19881 (diff) | |
Fix closed caption layout in the presence of italics / other markup (#3067).
| -rw-r--r-- | src/lib/layout_closed_captions.cc | 15 | ||||
| -rw-r--r-- | test/closed_caption_test.cc | 43 |
2 files changed, 57 insertions, 1 deletions
diff --git a/src/lib/layout_closed_captions.cc b/src/lib/layout_closed_captions.cc index 0f55f79f5..858b91c39 100644 --- a/src/lib/layout_closed_captions.cc +++ b/src/lib/layout_closed_captions.cc @@ -22,10 +22,12 @@ #include "dcpomatic_assert.h" #include "layout_closed_captions.h" #include "string_text.h" +#include "util.h" using std::string; using std::vector; +using boost::optional; vector<string> @@ -48,8 +50,19 @@ layout_closed_captions(vector<StringText> text) std::sort(text.begin(), text.end(), [&](StringText const & a, StringText const & b) { return from_top(a) < from_top(b); }); vector<string> strings; + string current; + optional<float> last_position; for (auto const& t: text) { - strings.push_back(t.text()); + if (last_position && !text_positions_close(*last_position, t.v_position()) && !current.empty()) { + strings.push_back(current); + current = ""; + } + current += t.text(); + last_position = t.v_position(); + } + + if (!current.empty()) { + strings.push_back(current); } return strings; diff --git a/test/closed_caption_test.cc b/test/closed_caption_test.cc index c8ef6865d..dc75bc5bd 100644 --- a/test/closed_caption_test.cc +++ b/test/closed_caption_test.cc @@ -20,6 +20,8 @@ #include "lib/film.h" +#include "lib/layout_closed_captions.h" +#include "lib/string_text.h" #include "lib/string_text_file_content.h" #include "lib/text_content.h" #include "test.h" @@ -32,6 +34,7 @@ using std::list; using std::make_shared; +using std::vector; /** Basic test that Interop closed captions are written */ @@ -121,3 +124,43 @@ BOOST_AUTO_TEST_CASE (closed_caption_test2) cl.run (); } + + +BOOST_AUTO_TEST_CASE(closed_captions_with_italics_test) +{ + vector<StringText> text = { + { + { + {}, false, true, true, {}, 42, 1, dcp::Time(0, 0, 0, 0, 24), dcp::Time(0, 0, 1, 0, 24), + 0, dcp::HAlign::CENTER, + 0, dcp::VAlign::CENTER, + 0, + {}, dcp::Direction::LTR, "Hello ", dcp::Effect::NONE, {}, {}, {}, 0, {} + }, 1, {}, dcp::SubtitleStandard::SMPTE_2014 + }, + { + { + {}, true, true, true, {}, 42, 1, dcp::Time(0, 0, 0, 0, 24), dcp::Time(0, 0, 1, 0, 24), + 0, dcp::HAlign::CENTER, + 0, dcp::VAlign::CENTER, + 0, + {}, dcp::Direction::LTR, "world", dcp::Effect::NONE, {}, {}, {}, 0, {} + }, 1, {}, dcp::SubtitleStandard::SMPTE_2014 + }, + { + { + {}, false, true, true, {}, 42, 1, dcp::Time(0, 0, 0, 0, 24), dcp::Time(0, 0, 1, 0, 24), + 0, dcp::HAlign::CENTER, + 4, dcp::VAlign::CENTER, + 0, + {}, dcp::Direction::LTR, "It's a new line", dcp::Effect::NONE, {}, {}, {}, 0, {} + }, 1, {}, dcp::SubtitleStandard::SMPTE_2014 + } + }; + + auto const strings = layout_closed_captions(text); + BOOST_REQUIRE_EQUAL(strings.size(), 2U); + BOOST_CHECK_EQUAL(strings[0], "Hello world"); + BOOST_CHECK_EQUAL(strings[1], "It's a new line"); +} + |
