Fix subtitle vertical position (#2367).
[dcpomatic.git] / src / lib / reel_writer.cc
index 4227a45fd01979c5de34dfe6473acc9c79c2a993..94b12ec7d38506147541c09d2b99634f82945a6d 100644 (file)
@@ -114,6 +114,7 @@ ReelWriter::ReelWriter (
        , _content_summary (film()->content_summary(period))
        , _job (job)
        , _text_only (text_only)
+       , _font_metrics(film()->frame_size().height)
 {
        /* Create or find our picture asset in a subdirectory, named
           according to those film's parameters which affect the video
@@ -871,6 +872,7 @@ ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track, bool
                                        dcp::HAlign::CENTER,
                                        0.5,
                                        dcp::VAlign::CENTER,
+                                       0,
                                        dcp::Direction::LTR,
                                        " ",
                                        dcp::Effect::NONE,
@@ -888,6 +890,33 @@ ReelWriter::empty_text_asset (TextType type, optional<DCPTextTrack> track, bool
 }
 
 
+float
+ReelWriter::convert_vertical_position(StringText const& subtitle, dcp::Standard to) const
+{
+       if (subtitle.valign_standard == to) {
+               return subtitle.v_position();
+       }
+
+       auto const baseline_to_bottom = _font_metrics.baseline_to_bottom(subtitle);
+       auto const height = _font_metrics.height(subtitle);
+
+       float correction = 0;
+       switch (subtitle.v_align()) {
+       case dcp::VAlign::TOP:
+               correction = height - baseline_to_bottom;
+               break;
+       case dcp::VAlign::CENTER:
+               correction = (height / 2) - baseline_to_bottom;
+               break;
+       case dcp::VAlign::BOTTOM:
+               correction = baseline_to_bottom;
+               break;
+       }
+
+       return subtitle.v_position() + ((subtitle.valign_standard == dcp::Standard::SMPTE) ? correction : -correction);
+}
+
+
 void
 ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track, DCPTimePeriod period, FontIdMap const& fonts)
 {
@@ -927,6 +956,7 @@ ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track,
        for (auto i: subs.string) {
                i.set_in  (dcp::Time(period.from.seconds() - _period.from.seconds(), tcr));
                i.set_out (dcp::Time(period.to.seconds() - _period.from.seconds(), tcr));
+               i.set_v_position(convert_vertical_position(i, film()->interop() ? dcp::Standard::INTEROP : dcp::Standard::SMPTE));
                auto sub = make_shared<dcp::SubtitleString>(i);
                if (type == TextType::OPEN_SUBTITLE) {
                        sub->set_font(fonts.get(i.font));
@@ -940,7 +970,7 @@ ReelWriter::write (PlayerText subs, TextType type, optional<DCPTextTrack> track,
                                image_as_png(i.image),
                                dcp::Time(period.from.seconds() - _period.from.seconds(), tcr),
                                dcp::Time(period.to.seconds() - _period.from.seconds(), tcr),
-                               i.rectangle.x, dcp::HAlign::LEFT, i.rectangle.y, dcp::VAlign::TOP,
+                               i.rectangle.x, dcp::HAlign::LEFT, i.rectangle.y, dcp::VAlign::TOP, 0,
                                dcp::Time(), dcp::Time()
                                )
                        );