From ac2fa2172c30c234a19628d7a9ae696e435a56db Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 8 Jul 2016 01:30:39 +0100 Subject: [PATCH] Support shadow in subtitles (#911). --- ChangeLog | 2 + src/lib/film.cc | 4 +- src/lib/player.cc | 3 +- src/lib/subtitle_content.cc | 45 ++++++++++++++++------- src/lib/subtitle_content.h | 19 +++++++--- src/lib/subtitle_decoder.cc | 11 +++++- src/wx/text_subtitle_appearance_dialog.cc | 26 +++++++++---- src/wx/text_subtitle_appearance_dialog.h | 7 ++-- 8 files changed, 84 insertions(+), 33 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a28623fa..55be07de3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ 2016-07-08 Carl Hetherington + * Support shadow in subtitles (#911). + * Version 2.9.0 released. 2016-07-07 Carl Hetherington diff --git a/src/lib/film.cc b/src/lib/film.cc index 3cd3f0f21..313170c21 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -114,8 +114,10 @@ using boost::is_any_of; * are present. * 34 -> 35 * VideoFrameType in VideoContent is a string rather than an integer. + * 35 -> 36 + * EffectColour rather than OutlineColour in Subtitle. */ -int const Film::current_state_version = 35; +int const Film::current_state_version = 36; /** Construct a Film object in a given directory. * diff --git a/src/lib/player.cc b/src/lib/player.cc index f8bfb527b..db62cbcc8 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -172,7 +172,8 @@ Player::playlist_content_changed (weak_ptr w, int property, bool freque property == DCPContentProperty::CAN_BE_PLAYED || property == SubtitleContentProperty::COLOUR || property == SubtitleContentProperty::OUTLINE || - property == SubtitleContentProperty::OUTLINE_COLOUR || + property == SubtitleContentProperty::SHADOW || + property == SubtitleContentProperty::EFFECT_COLOUR || property == FFmpegContentProperty::SUBTITLE_STREAM || property == VideoContentProperty::COLOUR_CONVERSION ) { diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc index fcc825026..2376aac68 100644 --- a/src/lib/subtitle_content.cc +++ b/src/lib/subtitle_content.cc @@ -49,8 +49,9 @@ int const SubtitleContentProperty::LANGUAGE = 506; int const SubtitleContentProperty::FONTS = 507; int const SubtitleContentProperty::COLOUR = 508; int const SubtitleContentProperty::OUTLINE = 509; -int const SubtitleContentProperty::OUTLINE_COLOUR = 510; -int const SubtitleContentProperty::LINE_SPACING = 511; +int const SubtitleContentProperty::SHADOW = 510; +int const SubtitleContentProperty::EFFECT_COLOUR = 511; +int const SubtitleContentProperty::LINE_SPACING = 512; SubtitleContent::SubtitleContent (Content* parent) : ContentPart (parent) @@ -62,7 +63,8 @@ SubtitleContent::SubtitleContent (Content* parent) , _y_scale (1) , _colour (255, 255, 255) , _outline (false) - , _outline_colour (0, 0, 0) + , _shadow (false) + , _effect_colour (0, 0, 0) , _line_spacing (1) { @@ -103,11 +105,7 @@ SubtitleContent::SubtitleContent (Content* parent, cxml::ConstNodePtr node, int node->optional_number_child("Blue").get_value_or(255) ) , _outline (node->optional_bool_child("Outline").get_value_or(false)) - , _outline_colour ( - node->optional_number_child("OutlineRed").get_value_or(255), - node->optional_number_child("OutlineGreen").get_value_or(255), - node->optional_number_child("OutlineBlue").get_value_or(255) - ) + , _shadow (node->optional_bool_child("Shadow").get_value_or(false)) , _line_spacing (node->optional_number_child("LineSpacing").get_value_or (1)) { if (version >= 32) { @@ -129,6 +127,20 @@ SubtitleContent::SubtitleContent (Content* parent, cxml::ConstNodePtr node, int _x_scale = _y_scale = node->number_child ("SubtitleScale"); } + if (version >= 36) { + _effect_colour = dcp::Colour ( + node->optional_number_child("EffectRed").get_value_or(255), + node->optional_number_child("EffectGreen").get_value_or(255), + node->optional_number_child("EffectBlue").get_value_or(255) + ); + } else { + _effect_colour = dcp::Colour ( + node->optional_number_child("OutlineRed").get_value_or(255), + node->optional_number_child("OutlineGreen").get_value_or(255), + node->optional_number_child("OutlineBlue").get_value_or(255) + ); + } + _language = node->optional_string_child ("SubtitleLanguage").get_value_or (""); list fonts = node->node_children ("Font"); @@ -223,9 +235,10 @@ SubtitleContent::as_xml (xmlpp::Node* root) const root->add_child("Green")->add_child_text (raw_convert (_colour.g)); root->add_child("Blue")->add_child_text (raw_convert (_colour.b)); root->add_child("Outline")->add_child_text (raw_convert (_outline)); - root->add_child("OutlineRed")->add_child_text (raw_convert (_outline_colour.r)); - root->add_child("OutlineGreen")->add_child_text (raw_convert (_outline_colour.g)); - root->add_child("OutlineBlue")->add_child_text (raw_convert (_outline_colour.b)); + root->add_child("Shadow")->add_child_text (raw_convert (_shadow)); + root->add_child("EffectRed")->add_child_text (raw_convert (_effect_colour.r)); + root->add_child("EffectGreen")->add_child_text (raw_convert (_effect_colour.g)); + root->add_child("EffectBlue")->add_child_text (raw_convert (_effect_colour.b)); root->add_child("LineSpacing")->add_child_text (raw_convert (_line_spacing)); for (list >::const_iterator i = _fonts.begin(); i != _fonts.end(); ++i) { @@ -299,9 +312,15 @@ SubtitleContent::set_outline (bool o) } void -SubtitleContent::set_outline_colour (dcp::Colour colour) +SubtitleContent::set_shadow (bool s) +{ + maybe_set (_shadow, s, SubtitleContentProperty::SHADOW); +} + +void +SubtitleContent::set_effect_colour (dcp::Colour colour) { - maybe_set (_outline_colour, colour, SubtitleContentProperty::OUTLINE_COLOUR); + maybe_set (_effect_colour, colour, SubtitleContentProperty::EFFECT_COLOUR); } void diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h index 6665f563a..c8492b91a 100644 --- a/src/lib/subtitle_content.h +++ b/src/lib/subtitle_content.h @@ -41,7 +41,8 @@ public: static int const FONTS; static int const COLOUR; static int const OUTLINE; - static int const OUTLINE_COLOUR; + static int const SHADOW; + static int const EFFECT_COLOUR; static int const LINE_SPACING; }; @@ -124,11 +125,18 @@ public: return _outline; } - void set_outline_colour (dcp::Colour); + void set_shadow (bool); - dcp::Colour outline_colour () const { + bool shadow () const { boost::mutex::scoped_lock lm (_mutex); - return _outline_colour; + return _shadow; + } + + void set_effect_colour (dcp::Colour); + + dcp::Colour effect_colour () const { + boost::mutex::scoped_lock lm (_mutex); + return _effect_colour; } void set_line_spacing (double s); @@ -168,7 +176,8 @@ private: std::list > _fonts; dcp::Colour _colour; bool _outline; - dcp::Colour _outline_colour; + bool _shadow; + dcp::Colour _effect_colour; std::list _font_connections; /** scaling factor for line spacing; 1 is "standard", < 1 is closer together, > 1 is further apart */ double _line_spacing; diff --git a/src/lib/subtitle_decoder.cc b/src/lib/subtitle_decoder.cc index 09f7a6700..b31b4873f 100644 --- a/src/lib/subtitle_decoder.cc +++ b/src/lib/subtitle_decoder.cc @@ -218,6 +218,13 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt } } + dcp::Effect effect = dcp::NONE; + if (content()->outline()) { + effect = dcp::BORDER; + } else if (content()->shadow()) { + effect = dcp::SHADOW; + } + out.push_back ( dcp::SubtitleString ( string(TEXT_FONT_ID), @@ -236,8 +243,8 @@ SubtitleDecoder::give_text (ContentTimePeriod period, sub::Subtitle const & subt v_align, dcp::DIRECTION_LTR, j.text, - content()->outline() ? dcp::BORDER : dcp::NONE, - content()->outline_colour(), + effect, + content()->effect_colour(), dcp::Time (0, 1000), dcp::Time (0, 1000) ) diff --git a/src/wx/text_subtitle_appearance_dialog.cc b/src/wx/text_subtitle_appearance_dialog.cc index 30402a63f..a826cbc66 100644 --- a/src/wx/text_subtitle_appearance_dialog.cc +++ b/src/wx/text_subtitle_appearance_dialog.cc @@ -34,20 +34,29 @@ TextSubtitleAppearanceDialog::TextSubtitleAppearanceDialog (wxWindow* parent, sh _colour = new wxColourPickerCtrl (this, wxID_ANY); add (_colour); - _outline = new wxCheckBox (this, wxID_ANY, _("Outline")); + wxRadioButton* no_effect = new wxRadioButton (this, wxID_ANY, _("No effect"), wxDefaultPosition, wxDefaultSize, wxRB_GROUP); + add (no_effect); + add_spacer (); + + _outline = new wxRadioButton (this, wxID_ANY, _("Outline")); add (_outline); add_spacer (); - add (_("Outline colour"), true); - _outline_colour = new wxColourPickerCtrl (this, wxID_ANY); - add (_outline_colour); + _shadow = new wxRadioButton (this, wxID_ANY, _("Shadow")); + add (_shadow); + add_spacer (); + + add (_("Outline / shadow colour"), true); + _effect_colour = new wxColourPickerCtrl (this, wxID_ANY); + add (_effect_colour); layout (); _colour->SetColour (wxColour (_content->colour().r, _content->colour().g, _content->colour().b)); _outline->SetValue (_content->outline ()); - _outline_colour->SetColour ( - wxColour (_content->outline_colour().r, _content->outline_colour().g, _content->outline_colour().b) + _shadow->SetValue (_content->shadow ()); + _effect_colour->SetColour ( + wxColour (_content->effect_colour().r, _content->effect_colour().g, _content->effect_colour().b) ); } @@ -57,6 +66,7 @@ TextSubtitleAppearanceDialog::apply () wxColour const c = _colour->GetColour (); _content->set_colour (dcp::Colour (c.Red(), c.Green(), c.Blue())); _content->set_outline (_outline->GetValue ()); - wxColour const oc = _outline_colour->GetColour (); - _content->set_outline_colour (dcp::Colour (oc.Red(), oc.Green(), oc.Blue())); + _content->set_shadow (_shadow->GetValue ()); + wxColour const ec = _effect_colour->GetColour (); + _content->set_effect_colour (dcp::Colour (ec.Red(), ec.Green(), ec.Blue())); } diff --git a/src/wx/text_subtitle_appearance_dialog.h b/src/wx/text_subtitle_appearance_dialog.h index feecae543..c67ec8756 100644 --- a/src/wx/text_subtitle_appearance_dialog.h +++ b/src/wx/text_subtitle_appearance_dialog.h @@ -21,7 +21,7 @@ #include "table_dialog.h" #include -class wxCheckBox; +class wxRadioButton; class wxColourPickerCtrl; class SubtitleContent; @@ -34,8 +34,9 @@ public: private: wxColourPickerCtrl* _colour; - wxCheckBox* _outline; - wxColourPickerCtrl* _outline_colour; + wxRadioButton* _outline; + wxRadioButton* _shadow; + wxColourPickerCtrl* _effect_colour; boost::shared_ptr _content; }; -- 2.30.2