X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Fsubrip_decoder.cc;h=2f8b8a5f36f4bccaa64543861cd58881f9c47421;hb=6cd300ca8513b360990360d2999bec3b8988fd97;hp=013c6fab7e6d2eab6f93b0ea290ac27fb3dae553;hpb=854f2e5bbb7ffb9758b823af87034033033f3cb8;p=dcpomatic.git diff --git a/src/lib/subrip_decoder.cc b/src/lib/subrip_decoder.cc index 013c6fab7..2f8b8a5f3 100644 --- a/src/lib/subrip_decoder.cc +++ b/src/lib/subrip_decoder.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2015 Carl Hetherington 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 @@ -17,59 +17,125 @@ */ -#include #include "subrip_decoder.h" +#include "subrip_content.h" +#include +#include +#include using std::list; +using std::vector; +using std::string; +using std::cout; +using std::max; using boost::shared_ptr; +using boost::optional; +using boost::dynamic_pointer_cast; SubRipDecoder::SubRipDecoder (shared_ptr content) - : SubRip (content) + : SubtitleDecoder (content) + , SubRip (content) , _next (0) { } void -SubRipDecoder::seek (ContentTime time, bool) +SubRipDecoder::seek (ContentTime time, bool accurate) { + SubtitleDecoder::seek (time, accurate); + _next = 0; - list::const_iterator i = _subtitles[_next].pieces.begin(); - while (i != _subtitles[_next].pieces.end() && _subtitles[_next].from < time) { - ++i; + while (_next < _subtitles.size() && ContentTime::from_seconds (_subtitles[_next].from.all_as_seconds ()) < time) { + ++_next; } - } bool -SubRipDecoder::pass () +SubRipDecoder::pass (PassReason, bool) { if (_next >= _subtitles.size ()) { return true; } - + + /* XXX: we are ignoring positioning specified in the file */ + + shared_ptr content = dynamic_pointer_cast (_subtitle_content); + DCPOMATIC_ASSERT (content); + list out; - for (list::const_iterator i = _subtitles[_next].pieces.begin(); i != _subtitles[_next].pieces.end(); ++i) { - out.push_back ( - dcp::SubtitleString ( - "Arial", - i->italic, - dcp::Color (255, 255, 255), - 72, - dcp::Time (rint (_subtitles[_next].from.seconds() * 250)), - dcp::Time (rint (_subtitles[_next].to.seconds() * 250)), - 0.9, - dcp::BOTTOM, - i->text, - dcp::NONE, - dcp::Color (255, 255, 255), - 0, - 0 - ) - ); + + /* Highest line index in this subtitle */ + int highest = 0; + BOOST_FOREACH (sub::Line i, _subtitles[_next].lines) { + DCPOMATIC_ASSERT (i.vertical_position.reference && i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE); + DCPOMATIC_ASSERT (i.vertical_position.line); + highest = max (highest, i.vertical_position.line.get()); + } + + BOOST_FOREACH (sub::Line i, _subtitles[_next].lines) { + BOOST_FOREACH (sub::Block j, i.blocks) { + out.push_back ( + dcp::SubtitleString ( + SubRipContent::font_id, + j.italic, + /* force the colour to whatever is configured */ + content->colour(), + j.font_size.points (72 * 11), + 1.0, + dcp::Time (_subtitles[_next].from.all_as_seconds(), 1000), + dcp::Time (_subtitles[_next].to.all_as_seconds(), 1000), + 0, + dcp::HALIGN_CENTER, + /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom + of the screen a bit to a pleasing degree. + */ + 1.015 - ((1 + highest - i.vertical_position.line.get()) * 1.5 / 22), + dcp::VALIGN_TOP, + j.text, + content->outline() ? dcp::BORDER : dcp::NONE, + content->outline_colour(), + dcp::Time (0, 1000), + dcp::Time (0, 1000) + ) + ); + } } - text_subtitle (out); - _next++; + text_subtitle (content_time_period (_subtitles[_next]), out); + + ++_next; return false; } + +list +SubRipDecoder::image_subtitles_during (ContentTimePeriod, bool) const +{ + return list (); +} + +list +SubRipDecoder::text_subtitles_during (ContentTimePeriod p, bool starting) const +{ + /* XXX: inefficient */ + + list d; + + for (vector::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) { + ContentTimePeriod t = content_time_period (*i); + if ((starting && p.contains (t.from)) || (!starting && p.overlaps (t))) { + d.push_back (t); + } + } + + return d; +} + +ContentTimePeriod +SubRipDecoder::content_time_period (sub::Subtitle s) const +{ + return ContentTimePeriod ( + ContentTime::from_seconds (s.from.all_as_seconds()), + ContentTime::from_seconds (s.to.all_as_seconds()) + ); +}