From 43d18fd59efb58004daa68f0161277efc423deef Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Wed, 22 May 2024 23:29:58 +0200 Subject: [PATCH] Support MarginL and MarginR in SSA subtitles (DoM #2811). --- src/ssa_reader.cc | 50 ++++++++++++++++++++++++++++++++- src/ssa_reader.h | 8 +++++- test/data/horizontal_margin.ssa | 23 +++++++++++++++ test/ssa_reader_test.cc | 46 ++++++++++++++++++++++++++---- 4 files changed, 119 insertions(+), 8 deletions(-) create mode 100644 test/data/horizontal_margin.ssa diff --git a/src/ssa_reader.cc b/src/ssa_reader.cc index 262bba7..1302b6b 100644 --- a/src/ssa_reader.cc +++ b/src/ssa_reader.cc @@ -149,6 +149,10 @@ public: } } else if (keys[i] == "MarginV") { vertical_margin = raw_convert (style[i]); + } else if (keys[i] == "MarginL") { + left_margin = raw_convert(style[i]); + } else if (keys[i] == "MarginR") { + right_margin = raw_convert(style[i]); } } } @@ -166,6 +170,8 @@ public: HorizontalReference horizontal_reference; VerticalReference vertical_reference; int vertical_margin; + int left_margin = 0; + int right_margin = 0; private: Colour colour (string c) const @@ -185,6 +191,24 @@ private: } }; + +void +SSAReader::Context::update_horizontal_position(RawSubtitle& sub) const +{ + switch (sub.horizontal_position.reference) { + case LEFT_OF_SCREEN: + sub.horizontal_position.proportional = static_cast(left_margin) / play_res_x; + break; + case HORIZONTAL_CENTRE_OF_SCREEN: + sub.horizontal_position.proportional = static_cast(left_margin - right_margin) / (2 * play_res_x); + break; + case RIGHT_OF_SCREEN: + sub.horizontal_position.proportional = static_cast(right_margin) / play_res_x; + break; + } +} + + Time SSAReader::parse_time (string t) const { @@ -218,30 +242,39 @@ SSAReader::parse_tag(RawSubtitle& sub, string tag, Context const& context) } else if (tag == "\\an1") { sub.horizontal_position.reference = sub::LEFT_OF_SCREEN; sub.vertical_position.reference = sub::BOTTOM_OF_SCREEN; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + 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; + context.update_horizontal_position(sub); } else if (boost::starts_with(tag, "\\pos")) { vector bits; boost::algorithm::split (bits, tag, boost::is_any_of("(,")); @@ -293,6 +326,8 @@ SSAReader::parse_line(RawSubtitle base, string line, Context const& context) */ 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. @@ -477,6 +512,8 @@ SSAReader::read (function ()> get_line) RawSubtitle sub; optional