+ auto wanted = [](ParseState const& ps) {
+ return ps.type && (ps.type.get() == ParseState::Type::TEXT || ps.type.get() == ParseState::Type::IMAGE);
+ };
+
+ if (find_if(parse_state.begin(), parse_state.end(), wanted) == parse_state.end()) {
+ return;
+ }
+
+ ParseState ps;
+ for (auto const& i: parse_state) {
+ if (i.font_id) {
+ ps.font_id = i.font_id.get();
+ }
+ if (i.size) {
+ ps.size = i.size.get();
+ }
+ if (i.aspect_adjust) {
+ ps.aspect_adjust = i.aspect_adjust.get();
+ }
+ if (i.italic) {
+ ps.italic = i.italic.get();
+ }
+ if (i.bold) {
+ ps.bold = i.bold.get();
+ }
+ if (i.underline) {
+ ps.underline = i.underline.get();
+ }
+ if (i.colour) {
+ ps.colour = i.colour.get();
+ }
+ if (i.effect) {
+ ps.effect = i.effect.get();
+ }
+ if (i.effect_colour) {
+ ps.effect_colour = i.effect_colour.get();
+ }
+ if (i.h_position) {
+ ps.h_position = i.h_position.get();
+ }
+ if (i.h_align) {
+ ps.h_align = i.h_align.get();
+ }
+ if (i.v_position) {
+ ps.v_position = i.v_position.get();
+ }
+ if (i.v_align) {
+ ps.v_align = i.v_align.get();
+ }
+ if (i.z_position) {
+ ps.z_position = i.z_position.get();
+ }
+ if (i.direction) {
+ ps.direction = i.direction.get();
+ }
+ if (i.in) {
+ ps.in = i.in.get();
+ }
+ if (i.out) {
+ ps.out = i.out.get();
+ }
+ if (i.fade_up_time) {
+ ps.fade_up_time = i.fade_up_time.get();
+ }
+ if (i.fade_down_time) {
+ ps.fade_down_time = i.fade_down_time.get();
+ }
+ if (i.type) {
+ ps.type = i.type.get();
+ }
+ }
+
+ if (!ps.in || !ps.out) {
+ /* We're not in a <Subtitle> node; just ignore this content */
+ return;
+ }
+
+ DCP_ASSERT (ps.type);
+
+ switch (ps.type.get()) {
+ case ParseState::Type::TEXT:
+ _subtitles.push_back (
+ make_shared<SubtitleString>(
+ ps.font_id,
+ ps.italic.get_value_or (false),
+ ps.bold.get_value_or (false),
+ ps.underline.get_value_or (false),
+ ps.colour.get_value_or (dcp::Colour (255, 255, 255)),
+ ps.size.get_value_or (42),
+ ps.aspect_adjust.get_value_or (1.0),
+ ps.in.get(),
+ ps.out.get(),
+ ps.h_position.get_value_or(0),
+ ps.h_align.get_value_or(HAlign::CENTER),
+ ps.v_position.get_value_or(0),
+ ps.v_align.get_value_or(VAlign::CENTER),
+ ps.z_position.get_value_or(0),
+ ps.direction.get_value_or (Direction::LTR),
+ text,
+ ps.effect.get_value_or (Effect::NONE),
+ ps.effect_colour.get_value_or (dcp::Colour (0, 0, 0)),
+ ps.fade_up_time.get_value_or(Time()),
+ ps.fade_down_time.get_value_or(Time()),
+ space_before
+ )
+ );
+ break;
+ case ParseState::Type::IMAGE:
+ {
+ switch (standard) {
+ case Standard::INTEROP:
+ if (text.size() >= 4) {
+ /* Remove file extension */
+ text = text.substr(0, text.size() - 4);
+ }
+ break;
+ case Standard::SMPTE:
+ /* It looks like this urn:uuid: is required, but DoM wasn't expecting it (and not writing it)
+ * until around 2.15.140 so I guess either:
+ * a) it is not (always) used in the field, or
+ * b) nobody noticed / complained.
+ */
+ if (text.substr(0, 9) == "urn:uuid:") {
+ text = text.substr(9);
+ }
+ break;
+ }
+
+ /* Add a subtitle with no image data and we'll fill that in later */
+ _subtitles.push_back (
+ make_shared<SubtitleImage>(
+ ArrayData(),
+ text,
+ ps.in.get(),
+ ps.out.get(),
+ ps.h_position.get_value_or(0),
+ ps.h_align.get_value_or(HAlign::CENTER),
+ ps.v_position.get_value_or(0),
+ ps.v_align.get_value_or(VAlign::CENTER),
+ ps.z_position.get_value_or(0),
+ ps.fade_up_time.get_value_or(Time()),
+ ps.fade_down_time.get_value_or(Time())
+ )
+ );
+ break;
+ }
+ }