+ list<dcp::SubtitleString> strings;
+
+ BOOST_FOREACH (shared_ptr<dcp::Subtitle> i, subs) {
+ shared_ptr<dcp::SubtitleString> is = dynamic_pointer_cast<dcp::SubtitleString> (i);
+ if (is) {
+ if (!strings.empty() && (strings.back().in() != is->in() || strings.back().out() != is->out())) {
+ dcp::SubtitleString b = strings.back();
+ decoder->emit_plain (
+ ContentTimePeriod (
+ ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.in().as_seconds()),
+ ContentTime::from_frames(_offset - entry_point, vfr) + ContentTime::from_seconds(b.out().as_seconds())
+ ),
+ strings
+ );
+ strings.clear ();
+ }
+
+ strings.push_back (*is);
+ }
+
+ shared_ptr<dcp::SubtitleImage> ii = dynamic_pointer_cast<dcp::SubtitleImage> (i);
+ if (ii) {
+ FFmpegImageProxy proxy (ii->png_image());
+ shared_ptr<Image> image = proxy.image().first;
+ /* set up rect with height and width */
+ dcpomatic::Rect<double> rect(0, 0, image->size().width / double(size.width), image->size().height / double(size.height));
+
+ /* add in position */
+
+ switch (ii->h_align()) {
+ case dcp::HALIGN_LEFT:
+ rect.x += ii->h_position();
+ break;
+ case dcp::HALIGN_CENTER:
+ rect.x += 0.5 + ii->h_position() - rect.width / 2;
+ break;
+ case dcp::HALIGN_RIGHT:
+ rect.x += 1 - ii->h_position() - rect.width;
+ break;
+ }
+
+ switch (ii->v_align()) {
+ case dcp::VALIGN_TOP:
+ rect.y += ii->v_position();
+ break;
+ case dcp::VALIGN_CENTER:
+ rect.y += 0.5 + ii->v_position() - rect.height / 2;
+ break;
+ case dcp::VALIGN_BOTTOM:
+ rect.y += 1 - ii->v_position() - rect.height;
+ break;
+ }
+
+ decoder->emit_bitmap (
+ ContentTimePeriod (
+ ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->in().as_seconds ()),
+ ContentTime::from_frames (_offset - entry_point, vfr) + ContentTime::from_seconds (i->out().as_seconds ())
+ ),
+ image, rect
+ );
+ }
+ }
+
+ if (!strings.empty()) {
+ dcp::SubtitleString b = strings.back();
+ decoder->emit_plain (