+ vector<dcp::SubtitleString> strings;
+
+ for (auto i: subs) {
+ auto is = dynamic_pointer_cast<const dcp::SubtitleString>(i);
+ if (is) {
+ if (!strings.empty() && (strings.back().in() != is->in() || strings.back().out() != is->out())) {
+ auto 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 ();
+ }
+
+ dcp::SubtitleString is_copy = *is;
+ is_copy.set_font(id_for_font_in_reel(is_copy.font().get_value_or(""), _reel - _reels.begin()));
+ strings.push_back(is_copy);
+ }
+
+ /* XXX: perhaps these image subs should also be collected together like the string ones are;
+ this would need to be done both here and in DCPSubtitleDecoder.
+ */
+
+ auto ii = dynamic_pointer_cast<const dcp::SubtitleImage>(i);
+ if (ii) {
+ emit_subtitle_image (
+ 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 ())
+ ),
+ *ii,
+ size,
+ decoder
+ );
+ }
+ }
+
+ if (!strings.empty()) {
+ auto b = strings.back();
+ decoder->emit_plain (