Make KDM output options checkboxes rather than radios (part of #848).
[dcpomatic.git] / src / lib / subtitle_decoder.cc
index f8f179587f6be35d85b10f0ff848a79d13639ef7..ba6fe460034c2f38dd0df54cf4314349dcfb369b 100644 (file)
@@ -29,6 +29,7 @@
 using std::list;
 using std::cout;
 using std::string;
+using std::min;
 using boost::shared_ptr;
 using boost::optional;
 using boost::function;
@@ -92,7 +93,7 @@ SubtitleDecoder::get (list<T> const & subs, list<ContentTimePeriod> const & sp,
 
        list<T> out;
        for (typename list<T>::const_iterator i = subs.begin(); i != subs.end(); ++i) {
-               if ((starting && period.contains (i->period().from)) || (!starting && period.overlaps (i->period ()))) {
+               if ((starting && period.contains(i->period().from)) || (!starting && period.overlap(i->period()))) {
                        out.push_back (*i);
                }
        }
@@ -131,6 +132,12 @@ SubtitleDecoder::get_image (ContentTimePeriod period, bool starting, bool accura
 
 void
 SubtitleDecoder::seek (ContentTime, bool)
+{
+       reset ();
+}
+
+void
+SubtitleDecoder::reset ()
 {
        _decoded_text.clear ();
        _decoded_image.clear ();
@@ -152,6 +159,18 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt
                }
        }
 
+       /* Find the lowest proportional postion */
+       optional<float> lowest_proportional;
+       BOOST_FOREACH (sub::Line i, subtitle.lines) {
+               if (i.vertical_position.proportional) {
+                       if (!lowest_proportional) {
+                               lowest_proportional = i.vertical_position.proportional;
+                       } else {
+                               lowest_proportional = min (lowest_proportional.get(), i.vertical_position.proportional.get());
+                       }
+               }
+       }
+
        list<dcp::SubtitleString> out;
        BOOST_FOREACH (sub::Line i, subtitle.lines) {
                BOOST_FOREACH (sub::Block j, i.blocks) {
@@ -165,15 +184,24 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt
                        dcp::VAlign v_align;
                        if (needs_placement) {
                                DCPOMATIC_ASSERT (i.vertical_position.line);
-                               /* This 0.053 is an arbitrary value to lift the bottom sub off the bottom
+                               /* This 1.015 is an arbitrary value to lift the bottom sub off the bottom
                                   of the screen a bit to a pleasing degree.
                                */
-                               v_position = 1.015 - (1 + bottom_line.get() - i.vertical_position.line.get()) * 1.2 * j.font_size.proportional (72 * 11);
+                               v_position = 1.015 -
+                                       (1 + bottom_line.get() - i.vertical_position.line.get())
+                                       * 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11);
+
                                v_align = dcp::VALIGN_TOP;
                        } else {
                                DCPOMATIC_ASSERT (i.vertical_position.proportional);
                                DCPOMATIC_ASSERT (i.vertical_position.reference);
                                v_position = i.vertical_position.proportional.get();
+
+                               if (lowest_proportional) {
+                                       /* Adjust line spacing */
+                                       v_position = ((v_position - lowest_proportional.get()) * content()->line_spacing()) + lowest_proportional.get();
+                               }
+
                                switch (i.vertical_position.reference.get()) {
                                case sub::TOP_OF_SCREEN:
                                        v_align = dcp::VALIGN_TOP;
@@ -190,11 +218,19 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt
                                }
                        }
 
+                       dcp::Effect effect = dcp::NONE;
+                       if (content()->outline()) {
+                               effect = dcp::BORDER;
+                       } else if (content()->shadow()) {
+                               effect = dcp::SHADOW;
+                       }
+
                        out.push_back (
                                dcp::SubtitleString (
                                        string(TEXT_FONT_ID),
                                        j.italic,
                                        j.bold,
+                                       j.underline,
                                        /* force the colour to whatever is configured */
                                        content()->colour(),
                                        j.font_size.points (72 * 11),
@@ -207,10 +243,10 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt
                                        v_align,
                                        dcp::DIRECTION_LTR,
                                        j.text,
-                                       content()->outline() ? dcp::BORDER : dcp::NONE,
-                                       content()->outline_colour(),
-                                       dcp::Time (0, 1000),
-                                       dcp::Time (0, 1000)
+                                       effect,
+                                       content()->effect_colour(),
+                                       dcp::Time (content()->fade_in().seconds(), 1000),
+                                       dcp::Time (content()->fade_out().seconds(), 1000)
                                        )
                                );
                }