X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Flib%2Ftext_content.cc;h=2584b5caaff85bec1c4dca472e5c6d4fcd988230;hb=9c8d2ed2e112596f7bb970d20f9240ec4519ec3e;hp=79ac42f43b25f7eb732d1925b71f37a8a016e525;hpb=8fedaaa75c4586a4cc7ffb393bd71d1fdb091dc8;p=dcpomatic.git diff --git a/src/lib/text_content.cc b/src/lib/text_content.cc index 79ac42f43..2584b5caa 100644 --- a/src/lib/text_content.cc +++ b/src/lib/text_content.cc @@ -18,6 +18,7 @@ */ + #include "text_content.h" #include "util.h" #include "exceptions.h" @@ -30,17 +31,19 @@ #include "i18n.h" -using std::string; -using std::vector; + using std::cout; +using std::dynamic_pointer_cast; using std::list; -using std::shared_ptr; using std::make_shared; -using std::dynamic_pointer_cast; +using std::shared_ptr; +using std::string; +using std::vector; using boost::optional; using dcp::raw_convert; using namespace dcpomatic; + int const TextContentProperty::X_OFFSET = 500; int const TextContentProperty::Y_OFFSET = 501; int const TextContentProperty::X_SCALE = 502; @@ -57,6 +60,9 @@ int const TextContentProperty::FADE_OUT = 512; int const TextContentProperty::OUTLINE_WIDTH = 513; int const TextContentProperty::TYPE = 514; int const TextContentProperty::DCP_TRACK = 515; +int const TextContentProperty::LANGUAGE = 516; +int const TextContentProperty::LANGUAGE_IS_ADDITIONAL = 517; + TextContent::TextContent (Content* parent, TextType type, TextType original_type) : ContentPart (parent) @@ -74,11 +80,12 @@ TextContent::TextContent (Content* parent, TextType type, TextType original_type } + /** @return TextContents from node or nodes under node (according to version). * The list could be empty if no TextContents are found. */ list> -TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version) +TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version, list& notes) { if (version < 34) { /* With old metadata FFmpeg content has the subtitle-related tags even with no @@ -95,24 +102,19 @@ TextContent::from_xml (Content* parent, cxml::ConstNodePtr node, int version) if (!node->optional_number_child("SubtitleXOffset") && !node->optional_number_child("SubtitleOffset")) { return {}; } - list> c; - c.push_back (make_shared(parent, node, version)); - return c; - } - - if (!node->optional_node_child("Text")) { - return {}; + return { make_shared(parent, node, version, notes) }; } list> c; for (auto i: node->node_children("Text")) { - c.push_back (make_shared(parent, i, version)); + c.push_back (make_shared(parent, i, version, notes)); } return c; } -TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version) + +TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version, list& notes) : ContentPart (parent) , _use (false) , _burn (false) @@ -231,8 +233,31 @@ TextContent::TextContent (Content* parent, cxml::ConstNodePtr node, int version) if (dt) { _dcp_track = DCPTextTrack (dt); } + + auto lang = node->optional_node_child("Language"); + if (lang) { + try { + _language = dcp::LanguageTag(lang->content()); + auto add = lang->optional_bool_attribute("Additional"); + _language_is_additional = add && *add; + } catch (dcp::LanguageTagError&) { + /* The language tag can be empty or invalid if it was loaded from a + * 2.14.x metadata file; we'll just ignore it in that case. + */ + if (version <= 37) { + if (!lang->content().empty()) { + notes.push_back (String::compose( + _("A subtitle or closed caption file in this project is marked with the language '%1', " + "which DCP-o-matic does not recognise. The file's language has been cleared."), lang->content())); + } + } else { + throw; + } + } + } } + TextContent::TextContent (Content* parent, vector> c) : ContentPart (parent) { @@ -290,6 +315,14 @@ TextContent::TextContent (Content* parent, vector> c) throw JoinError (_("Content to be joined must use the same DCP track.")); } + if (c[i]->only_text()->language() != ref->language()) { + throw JoinError (_("Content to be joined must use the same text language.")); + } + + if (c[i]->only_text()->language_is_additional() != ref->language_is_additional()) { + throw JoinError (_("Content to be joined must both be main subtitle languages or both additional.")); + } + auto j = ref_fonts.begin (); auto k = fonts.begin (); @@ -316,10 +349,13 @@ TextContent::TextContent (Content* parent, vector> c) _type = ref->type (); _original_type = ref->original_type (); _dcp_track = ref->dcp_track (); + _language = ref->language (); + _language_is_additional = ref->language_is_additional (); connect_to_fonts (); } + /** _mutex must not be held on entry */ void TextContent::as_xml (xmlpp::Node* root) const @@ -375,8 +411,14 @@ TextContent::as_xml (xmlpp::Node* root) const if (_dcp_track) { _dcp_track->as_xml(text->add_child("DCPTrack")); } + if (_language) { + auto lang = text->add_child("Language"); + lang->add_child_text (_language->to_string()); + lang->set_attribute ("Additional", _language_is_additional ? "1" : "0"); + } } + string TextContent::identifier () const { @@ -400,11 +442,12 @@ TextContent::identifier () const s += "_" + f->file().get_value_or("Default").string(); } - /* The DCP track is for metadata only, and doesn't affect how this content looks */ + /* The DCP track and language are for metadata only, and don't affect how this content looks */ return s; } + void TextContent::add_font (shared_ptr font) { @@ -412,6 +455,7 @@ TextContent::add_font (shared_ptr font) connect_to_fonts (); } + void TextContent::connect_to_fonts () { @@ -426,139 +470,176 @@ TextContent::connect_to_fonts () } } + void TextContent::font_changed () { /* XXX: too late */ - ChangeSignaller cc (_parent, TextContentProperty::FONTS); + ContentChangeSignaller cc (_parent, TextContentProperty::FONTS); } + void TextContent::set_colour (dcp::Colour colour) { maybe_set (_colour, colour, TextContentProperty::COLOUR); } + void TextContent::unset_colour () { maybe_set (_colour, optional(), TextContentProperty::COLOUR); } + void TextContent::set_effect (dcp::Effect e) { maybe_set (_effect, e, TextContentProperty::EFFECT); } + void TextContent::unset_effect () { maybe_set (_effect, optional(), TextContentProperty::EFFECT); } + void TextContent::set_effect_colour (dcp::Colour colour) { maybe_set (_effect_colour, colour, TextContentProperty::EFFECT_COLOUR); } + void TextContent::unset_effect_colour () { maybe_set (_effect_colour, optional(), TextContentProperty::EFFECT_COLOUR); } + void TextContent::set_use (bool u) { maybe_set (_use, u, TextContentProperty::USE); } + void TextContent::set_burn (bool b) { maybe_set (_burn, b, TextContentProperty::BURN); } + void TextContent::set_x_offset (double o) { maybe_set (_x_offset, o, TextContentProperty::X_OFFSET); } + void TextContent::set_y_offset (double o) { maybe_set (_y_offset, o, TextContentProperty::Y_OFFSET); } + void TextContent::set_x_scale (double s) { maybe_set (_x_scale, s, TextContentProperty::X_SCALE); } + void TextContent::set_y_scale (double s) { maybe_set (_y_scale, s, TextContentProperty::Y_SCALE); } + void TextContent::set_line_spacing (double s) { maybe_set (_line_spacing, s, TextContentProperty::LINE_SPACING); } + void TextContent::set_fade_in (ContentTime t) { maybe_set (_fade_in, t, TextContentProperty::FADE_IN); } + void TextContent::unset_fade_in () { maybe_set (_fade_in, optional(), TextContentProperty::FADE_IN); } + void TextContent::set_fade_out (ContentTime t) { maybe_set (_fade_out, t, TextContentProperty::FADE_OUT); } + void TextContent::unset_fade_out () { maybe_set (_fade_out, optional(), TextContentProperty::FADE_OUT); } + void TextContent::set_type (TextType type) { maybe_set (_type, type, TextContentProperty::TYPE); } + void TextContent::set_outline_width (int w) { maybe_set (_outline_width, w, TextContentProperty::OUTLINE_WIDTH); } + void TextContent::set_dcp_track (DCPTextTrack t) { maybe_set (_dcp_track, t, TextContentProperty::DCP_TRACK); } + void TextContent::unset_dcp_track () { maybe_set (_dcp_track, optional(), TextContentProperty::DCP_TRACK); } + +void +TextContent::set_language (optional language) +{ + maybe_set (_language, language, TextContentProperty::LANGUAGE); +} + + +void +TextContent::set_language_is_additional (bool additional) +{ + maybe_set (_language_is_additional, additional, TextContentProperty::LANGUAGE_IS_ADDITIONAL); +} + + void TextContent::take_settings_from (shared_ptr c) { @@ -595,4 +676,6 @@ TextContent::take_settings_from (shared_ptr c) } else { unset_dcp_track (); } + set_language (c->_language); + set_language_is_additional (c->_language_is_additional); }