X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Ftext_decoder.cc;h=8146d33aa416e3d6574c0be4b3898c377ecec2e7;hb=2f796cd531de522a3b7ed03a9942f3c55f3a0b5b;hp=4eaaf37af7cbd50b86ad2fdce8bfbc17253c88c3;hpb=c4403784febdbdd42e9c32e67fadb147f11fe566;p=dcpomatic.git diff --git a/src/lib/text_decoder.cc b/src/lib/text_decoder.cc index 4eaaf37af..8146d33aa 100644 --- a/src/lib/text_decoder.cc +++ b/src/lib/text_decoder.cc @@ -33,6 +33,7 @@ using std::list; using std::cout; using std::string; using std::min; +using std::max; using boost::shared_ptr; using boost::optional; using boost::function; @@ -105,9 +106,8 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle) bool needs_placement = false; optional bottom_line; BOOST_FOREACH (sub::Line i, subtitle.lines) { - if (!i.vertical_position.reference || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) { + if (!i.vertical_position.reference || (i.vertical_position.line && !i.vertical_position.lines) || i.vertical_position.reference.get() == sub::TOP_OF_SUBTITLE) { needs_placement = true; - DCPOMATIC_ASSERT (i.vertical_position.line); if (!bottom_line || bottom_line.get() < i.vertical_position.line.get()) { bottom_line = i.vertical_position.line.get(); } @@ -139,18 +139,37 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle) dcp::VAlign v_align; if (needs_placement) { DCPOMATIC_ASSERT (i.vertical_position.line); - /* 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 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11); + double const multiplier = 1.2 * content()->line_spacing() * content()->y_scale() * j.font_size.proportional (72 * 11); + switch (i.vertical_position.reference.get_value_or(sub::BOTTOM_OF_SCREEN)) { + case sub::BOTTOM_OF_SCREEN: + case sub::TOP_OF_SUBTITLE: + /* 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()) * multiplier; - v_align = dcp::VALIGN_TOP; + v_align = dcp::VALIGN_TOP; + break; + case sub::TOP_OF_SCREEN: + /* This 0.1 is another fudge factor to bring the top line away from the top of the screen a little */ + v_position = 0.12 + i.vertical_position.line.get() * multiplier; + v_align = dcp::VALIGN_TOP; + break; + case sub::VERTICAL_CENTRE_OF_SCREEN: + v_position = i.vertical_position.line.get() * multiplier; + v_align = dcp::VALIGN_CENTER; + break; + } } else { - DCPOMATIC_ASSERT (i.vertical_position.proportional); DCPOMATIC_ASSERT (i.vertical_position.reference); - v_position = i.vertical_position.proportional.get(); + if (i.vertical_position.proportional) { + v_position = i.vertical_position.proportional.get(); + } else { + DCPOMATIC_ASSERT (i.vertical_position.line); + DCPOMATIC_ASSERT (i.vertical_position.lines); + v_position = float(*i.vertical_position.line) / *i.vertical_position.lines; + } if (lowest_proportional) { /* Adjust line spacing */ @@ -174,15 +193,18 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle) } dcp::HAlign h_align; + float h_position = i.horizontal_position.proportional; switch (i.horizontal_position.reference) { case sub::LEFT_OF_SCREEN: h_align = dcp::HALIGN_LEFT; + h_position = max(h_position, 0.05f); break; case sub::HORIZONTAL_CENTRE_OF_SCREEN: h_align = dcp::HALIGN_CENTER; break; case sub::RIGHT_OF_SCREEN: h_align = dcp::HALIGN_RIGHT; + h_position = max(h_position, 0.05f); break; default: h_align = dcp::HALIGN_CENTER; @@ -206,7 +228,7 @@ TextDecoder::emit_plain_start (ContentTime from, sub::Subtitle const & subtitle) dcp::Time (from.seconds(), 1000), /* XXX: hmm; this is a bit ugly (we don't know the to time yet) */ dcp::Time (), - i.horizontal_position.proportional, + h_position, h_align, v_position, v_align,