diff options
Diffstat (limited to 'src/stl_binary_writer.cc')
| -rw-r--r-- | src/stl_binary_writer.cc | 150 |
1 files changed, 86 insertions, 64 deletions
diff --git a/src/stl_binary_writer.cc b/src/stl_binary_writer.cc index 9931985..baed8d8 100644 --- a/src/stl_binary_writer.cc +++ b/src/stl_binary_writer.cc @@ -170,9 +170,10 @@ sub::write_stl_binary ( ofstream output (file_name.string().c_str ()); STLBinaryTables tables; - /* Find the longest subtitle in characters and count the number of lines we have */ + /* Find the longest subtitle in characters */ + int longest = 0; - int lines = 0; + BOOST_FOREACH (Subtitle const& i, subtitles) { BOOST_FOREACH (Line const& j, i.lines) { int t = 0; @@ -180,7 +181,6 @@ sub::write_stl_binary ( t += k.text.size (); } longest = std::max (longest, t); - ++lines; } } @@ -205,7 +205,7 @@ sub::write_stl_binary ( put_string (buffer + 230, revision_date); put_int_as_string (buffer + 236, revision_number, 2); /* TTI blocks */ - put_int_as_string (buffer + 238, lines, 5); + put_int_as_string (buffer + 238, subtitles.size(), 5); /* Total number of subtitles */ put_int_as_string (buffer + 243, subtitles.size(), 5); /* Total number of subtitle groups */ @@ -233,53 +233,76 @@ sub::write_stl_binary ( BOOST_FOREACH (Subtitle const& i, subtitles) { - size_t line = 0; + /* Find the top vertical position of this subtitle */ + optional<int> top; BOOST_FOREACH (Line const& j, i.lines) { - - memset (buffer, 0, 128); - - /* XXX: these should increment, surely! */ - /* Subtitle group number */ - put_int_as_int (buffer + 0, 1, 1); - /* Subtitle number */ - put_int_as_int (buffer + 1, 0, 2); - /* Extension block number. These are indexed from zero except the last one is 255 */ - put_int_as_int (buffer + 3, line == (i.lines.size() - 1) ? 255 : line, 1); - /* Cumulative status */ - put_int_as_int (buffer + 4, tables.cumulative_status_enum_to_file (CUMULATIVE_STATUS_NOT_CUMULATIVE), 1); - /* Time code in */ - put_int_as_int (buffer + 5, i.from.hours(), 1); - put_int_as_int (buffer + 6, i.from.minutes(), 1); - put_int_as_int (buffer + 7, i.from.seconds(), 1); - put_int_as_int (buffer + 8, i.from.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1); - /* Time code out */ - put_int_as_int (buffer + 9, i.to.hours(), 1); - put_int_as_int (buffer + 10, i.to.minutes(), 1); - put_int_as_int (buffer + 11, i.to.seconds(), 1); - put_int_as_int (buffer + 12, i.to.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1); - /* Vertical position */ - put_int_as_int (buffer + 13, vertical_position(j), 1); - - /* Justification code */ - switch (j.horizontal_position.reference) { - case LEFT_OF_SCREEN: - put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_LEFT), 1); - break; - case HORIZONTAL_CENTRE_OF_SCREEN: - put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_CENTRE), 1); - break; - case RIGHT_OF_SCREEN: - put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_RIGHT), 1); - break; + int const vp = vertical_position (j); + if (!top || vp < top.get ()) { + top = vp; } + } + + memset (buffer, 0, 128); + + /* XXX: these should increment, surely! */ + /* Subtitle group number */ + put_int_as_int (buffer + 0, 1, 1); + /* Subtitle number */ + put_int_as_int (buffer + 1, 0, 2); + /* Extension block number. Use 0xff here to indicate that it is the last TTI + block in this subtitle "set", as we only ever use one. + */ + put_int_as_int (buffer + 3, 255, 1); + /* Cumulative status */ + put_int_as_int (buffer + 4, tables.cumulative_status_enum_to_file (CUMULATIVE_STATUS_NOT_CUMULATIVE), 1); + /* Time code in */ + put_int_as_int (buffer + 5, i.from.hours(), 1); + put_int_as_int (buffer + 6, i.from.minutes(), 1); + put_int_as_int (buffer + 7, i.from.seconds(), 1); + put_int_as_int (buffer + 8, i.from.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1); + /* Time code out */ + put_int_as_int (buffer + 9, i.to.hours(), 1); + put_int_as_int (buffer + 10, i.to.minutes(), 1); + put_int_as_int (buffer + 11, i.to.seconds(), 1); + put_int_as_int (buffer + 12, i.to.frames_at(sub::Rational(frames_per_second * 1000, 1000)), 1); + /* Vertical position */ + put_int_as_int (buffer + 13, top.get(), 1); + + /* Justification code */ + /* XXX: this assumes the first line has the right value */ + switch (i.lines.front().horizontal_position.reference) { + case LEFT_OF_SCREEN: + put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_LEFT), 1); + break; + case HORIZONTAL_CENTRE_OF_SCREEN: + put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_CENTRE), 1); + break; + case RIGHT_OF_SCREEN: + put_int_as_int (buffer + 14, tables.justification_enum_to_file (JUSTIFICATION_RIGHT), 1); + break; + } + + /* Comment flag */ + put_int_as_int (buffer + 15, tables.comment_enum_to_file (COMMENT_NO), 1); + + /* Text */ + string text; + bool italic = false; + bool underline = false; + optional<int> last_vp; + + BOOST_FOREACH (Line const& j, i.lines) { - /* Comment flag */ - put_int_as_int (buffer + 15, tables.comment_enum_to_file (COMMENT_NO), 1); + /* CR/LF down to this line */ + int const vp = vertical_position (j); - /* Text */ - string text; - bool italic = false; - bool underline = false; + if (last_vp) { + for (int k = last_vp.get(); k < vp; ++k) { + text += "\x8A"; + } + } + + last_vp = vp; BOOST_FOREACH (Block const& k, j.blocks) { if (k.underline && !underline) { @@ -299,29 +322,28 @@ sub::write_stl_binary ( text += utf16_to_iso6937 (utf_to_utf<wchar_t> (k.text)); } + } - /* Turn italic/underline off before the end of this subtitle */ - - if (underline) { - text += "\x83"; - } + /* Turn italic/underline off before the end of this subtitle */ - if (italic) { - text += "\x81"; - } + if (underline) { + text += "\x83"; + } - if (text.length() > 111) { - text = text.substr (111); - } + if (italic) { + text += "\x81"; + } - while (text.length() < 112) { - text += "\x8F"; - } + if (text.length() > 111) { + text = text.substr (111); + } - put_string (buffer + 16, text); - output.write (buffer, 128); - ++line; + while (text.length() < 112) { + text += "\x8F"; } + + put_string (buffer + 16, text); + output.write (buffer, 128); } delete[] buffer; |
