diff options
| author | Carl Hetherington <cth@carlh.net> | 2014-01-29 22:03:05 +0000 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2014-01-29 22:03:05 +0000 |
| commit | 62a1e9d6cda70050b813d4ba0c3e83b7350f360d (patch) | |
| tree | a2aaf87d4f41544a497b9a9ea65203048b1406d5 /src | |
| parent | 4c2ae591ee17599b4fbb7ffc24a06f27ed985c05 (diff) | |
Add subtitle X offset option.
Suggested-by: Thierry Journet
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/ffmpeg_content.cc | 2 | ||||
| -rw-r--r-- | src/lib/film.cc | 4 | ||||
| -rw-r--r-- | src/lib/player.cc | 9 | ||||
| -rw-r--r-- | src/lib/subtitle_content.cc | 51 | ||||
| -rw-r--r-- | src/lib/subtitle_content.h | 29 | ||||
| -rw-r--r-- | src/wx/subtitle_panel.cc | 46 | ||||
| -rw-r--r-- | src/wx/subtitle_panel.h | 6 |
7 files changed, 108 insertions, 39 deletions
diff --git a/src/lib/ffmpeg_content.cc b/src/lib/ffmpeg_content.cc index f59551d1d..2c5fcf70e 100644 --- a/src/lib/ffmpeg_content.cc +++ b/src/lib/ffmpeg_content.cc @@ -62,7 +62,7 @@ FFmpegContent::FFmpegContent (shared_ptr<const Film> f, shared_ptr<const cxml::N : Content (f, node) , VideoContent (f, node) , AudioContent (f, node) - , SubtitleContent (f, node) + , SubtitleContent (f, node, version) { list<cxml::NodePtr> c = node->node_children ("SubtitleStream"); for (list<cxml::NodePtr>::const_iterator i = c.begin(); i != c.end(); ++i) { diff --git a/src/lib/film.cc b/src/lib/film.cc index 1290cbda2..8690d3ee0 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -83,8 +83,10 @@ using libdcp::Signer; /* 5 -> 6 * AudioMapping XML changed. + * 6 -> 7 + * Subtitle offset changed to subtitle y offset, and subtitle x offset added. */ -int const Film::state_version = 6; +int const Film::state_version = 7; /** Construct a Film object in a given directory. * diff --git a/src/lib/player.cc b/src/lib/player.cc index 1c54d0fc5..e661a7b36 100644 --- a/src/lib/player.cc +++ b/src/lib/player.cc @@ -521,7 +521,11 @@ Player::content_changed (weak_ptr<Content> w, int property, bool frequent) _have_valid_pieces = false; Changed (frequent); - } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET || property == SubtitleContentProperty::SUBTITLE_SCALE) { + } else if ( + property == SubtitleContentProperty::SUBTITLE_X_OFFSET || + property == SubtitleContentProperty::SUBTITLE_Y_OFFSET || + property == SubtitleContentProperty::SUBTITLE_SCALE + ) { update_subtitle (); Changed (frequent); @@ -658,7 +662,8 @@ Player::update_subtitle () dcpomatic::Rect<double> in_rect = _in_subtitle.rect; libdcp::Size scaled_size; - in_rect.y += sc->subtitle_offset (); + in_rect.x += sc->subtitle_x_offset (); + in_rect.y += sc->subtitle_y_offset (); /* We will scale the subtitle up to fit _video_container_size, and also by the additional subtitle_scale */ scaled_size.width = in_rect.width * _video_container_size.width * sc->subtitle_scale (); diff --git a/src/lib/subtitle_content.cc b/src/lib/subtitle_content.cc index 6c0d3af86..8f88574e5 100644 --- a/src/lib/subtitle_content.cc +++ b/src/lib/subtitle_content.cc @@ -30,25 +30,34 @@ using boost::shared_ptr; using boost::lexical_cast; using boost::dynamic_pointer_cast; -int const SubtitleContentProperty::SUBTITLE_OFFSET = 500; -int const SubtitleContentProperty::SUBTITLE_SCALE = 501; +int const SubtitleContentProperty::SUBTITLE_X_OFFSET = 500; +int const SubtitleContentProperty::SUBTITLE_Y_OFFSET = 501; +int const SubtitleContentProperty::SUBTITLE_SCALE = 502; SubtitleContent::SubtitleContent (shared_ptr<const Film> f, boost::filesystem::path p) : Content (f, p) - , _subtitle_offset (0) + , _subtitle_x_offset (0) + , _subtitle_y_offset (0) , _subtitle_scale (1) { } -SubtitleContent::SubtitleContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node) +SubtitleContent::SubtitleContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version) : Content (f, node) - , _subtitle_offset (0) + , _subtitle_x_offset (0) + , _subtitle_y_offset (0) , _subtitle_scale (1) { LocaleGuard lg; + + if (version >= 7) { + _subtitle_x_offset = node->number_child<float> ("SubtitleXOffset"); + _subtitle_y_offset = node->number_child<float> ("SubtitleYOffset"); + } else { + _subtitle_y_offset = node->number_child<float> ("SubtitleOffset"); + } - _subtitle_offset = node->number_child<float> ("SubtitleOffset"); _subtitle_scale = node->number_child<float> ("SubtitleScale"); } @@ -61,8 +70,12 @@ SubtitleContent::SubtitleContent (shared_ptr<const Film> f, vector<shared_ptr<Co for (size_t i = 0; i < c.size(); ++i) { shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (c[i]); - if (sc->subtitle_offset() != ref->subtitle_offset()) { - throw JoinError (_("Content to be joined must have the same subtitle offset.")); + if (sc->subtitle_x_offset() != ref->subtitle_x_offset()) { + throw JoinError (_("Content to be joined must have the same subtitle X offset.")); + } + + if (sc->subtitle_y_offset() != ref->subtitle_y_offset()) { + throw JoinError (_("Content to be joined must have the same subtitle Y offset.")); } if (sc->subtitle_scale() != ref->subtitle_scale()) { @@ -70,7 +83,8 @@ SubtitleContent::SubtitleContent (shared_ptr<const Film> f, vector<shared_ptr<Co } } - _subtitle_offset = ref->subtitle_offset (); + _subtitle_x_offset = ref->subtitle_x_offset (); + _subtitle_y_offset = ref->subtitle_y_offset (); _subtitle_scale = ref->subtitle_scale (); } @@ -79,18 +93,29 @@ SubtitleContent::as_xml (xmlpp::Node* root) const { LocaleGuard lg; - root->add_child("SubtitleOffset")->add_child_text (lexical_cast<string> (_subtitle_offset)); + root->add_child("SubtitleXOffset")->add_child_text (lexical_cast<string> (_subtitle_x_offset)); + root->add_child("SubtitleYOffset")->add_child_text (lexical_cast<string> (_subtitle_y_offset)); root->add_child("SubtitleScale")->add_child_text (lexical_cast<string> (_subtitle_scale)); } void -SubtitleContent::set_subtitle_offset (double o) +SubtitleContent::set_subtitle_x_offset (double o) +{ + { + boost::mutex::scoped_lock lm (_mutex); + _subtitle_x_offset = o; + } + signal_changed (SubtitleContentProperty::SUBTITLE_X_OFFSET); +} + +void +SubtitleContent::set_subtitle_y_offset (double o) { { boost::mutex::scoped_lock lm (_mutex); - _subtitle_offset = o; + _subtitle_y_offset = o; } - signal_changed (SubtitleContentProperty::SUBTITLE_OFFSET); + signal_changed (SubtitleContentProperty::SUBTITLE_Y_OFFSET); } void diff --git a/src/lib/subtitle_content.h b/src/lib/subtitle_content.h index 854647d18..388637688 100644 --- a/src/lib/subtitle_content.h +++ b/src/lib/subtitle_content.h @@ -25,7 +25,8 @@ class SubtitleContentProperty { public: - static int const SUBTITLE_OFFSET; + static int const SUBTITLE_X_OFFSET; + static int const SUBTITLE_Y_OFFSET; static int const SUBTITLE_SCALE; }; @@ -33,17 +34,23 @@ class SubtitleContent : public virtual Content { public: SubtitleContent (boost::shared_ptr<const Film>, boost::filesystem::path); - SubtitleContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>); + SubtitleContent (boost::shared_ptr<const Film>, boost::shared_ptr<const cxml::Node>, int version); SubtitleContent (boost::shared_ptr<const Film>, std::vector<boost::shared_ptr<Content> >); void as_xml (xmlpp::Node *) const; - void set_subtitle_offset (double); + void set_subtitle_x_offset (double); + void set_subtitle_y_offset (double); void set_subtitle_scale (double); - double subtitle_offset () const { + double subtitle_x_offset () const { boost::mutex::scoped_lock lm (_mutex); - return _subtitle_offset; + return _subtitle_x_offset; + } + + double subtitle_y_offset () const { + boost::mutex::scoped_lock lm (_mutex); + return _subtitle_y_offset; } double subtitle_scale () const { @@ -53,11 +60,15 @@ public: private: friend class ffmpeg_pts_offset_test; - + + /** x offset for placing subtitles, as a proportion of the container width; + * +ve is further right, -ve is further left. + */ + double _subtitle_x_offset; /** y offset for placing subtitles, as a proportion of the container height; - +ve is further down the frame, -ve is further up. - */ - double _subtitle_offset; + * +ve is further down the frame, -ve is further up. + */ + double _subtitle_y_offset; /** scale factor to apply to subtitles */ double _subtitle_scale; }; diff --git a/src/wx/subtitle_panel.cc b/src/wx/subtitle_panel.cc index 0e3f2e89d..02c8776d6 100644 --- a/src/wx/subtitle_panel.cc +++ b/src/wx/subtitle_panel.cc @@ -41,15 +41,24 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e) grid->AddSpacer (0); { - add_label_to_sizer (grid, this, _("Subtitle Offset"), true); + add_label_to_sizer (grid, this, _("Subtitle X Offset"), true); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); - _offset = new wxSpinCtrl (this); - s->Add (_offset); + _x_offset = new wxSpinCtrl (this); + s->Add (_x_offset); add_label_to_sizer (s, this, _("%"), false); grid->Add (s); } { + add_label_to_sizer (grid, this, _("Subtitle Y Offset"), true); + wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); + _y_offset = new wxSpinCtrl (this); + s->Add (_y_offset); + add_label_to_sizer (s, this, _("%"), false); + grid->Add (s); + } + + { add_label_to_sizer (grid, this, _("Subtitle Scale"), true); wxBoxSizer* s = new wxBoxSizer (wxHORIZONTAL); _scale = new wxSpinCtrl (this); @@ -62,12 +71,14 @@ SubtitlePanel::SubtitlePanel (FilmEditor* e) _stream = new wxChoice (this, wxID_ANY); grid->Add (_stream, 1, wxEXPAND); - _offset->SetRange (-100, 100); + _x_offset->SetRange (-100, 100); + _y_offset->SetRange (-100, 100); _scale->SetRange (1, 1000); _scale->SetValue (100); _with_subtitles->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&SubtitlePanel::with_subtitles_toggled, this)); - _offset->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::offset_changed, this)); + _x_offset->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::x_offset_changed, this)); + _y_offset->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::y_offset_changed, this)); _scale->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&SubtitlePanel::scale_changed, this)); _stream->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&SubtitlePanel::stream_changed, this)); } @@ -119,8 +130,10 @@ SubtitlePanel::film_content_changed (int property) } } setup_sensitivity (); - } else if (property == SubtitleContentProperty::SUBTITLE_OFFSET) { - checked_set (_offset, scs ? (scs->subtitle_offset() * 100) : 0); + } else if (property == SubtitleContentProperty::SUBTITLE_X_OFFSET) { + checked_set (_x_offset, scs ? (scs->subtitle_x_offset() * 100) : 0); + } else if (property == SubtitleContentProperty::SUBTITLE_Y_OFFSET) { + checked_set (_y_offset, scs ? (scs->subtitle_y_offset() * 100) : 0); } else if (property == SubtitleContentProperty::SUBTITLE_SCALE) { checked_set (_scale, scs ? (scs->subtitle_scale() * 100) : 100); } @@ -147,7 +160,8 @@ SubtitlePanel::setup_sensitivity () } _with_subtitles->Enable (h); - _offset->Enable (j); + _x_offset->Enable (j); + _y_offset->Enable (j); _scale->Enable (j); _stream->Enable (j); } @@ -175,11 +189,20 @@ SubtitlePanel::stream_changed () } void -SubtitlePanel::offset_changed () +SubtitlePanel::x_offset_changed () +{ + SubtitleContentList c = _editor->selected_subtitle_content (); + if (c.size() == 1) { + c.front()->set_subtitle_x_offset (_x_offset->GetValue() / 100.0); + } +} + +void +SubtitlePanel::y_offset_changed () { SubtitleContentList c = _editor->selected_subtitle_content (); if (c.size() == 1) { - c.front()->set_subtitle_offset (_offset->GetValue() / 100.0); + c.front()->set_subtitle_y_offset (_y_offset->GetValue() / 100.0); } } @@ -196,6 +219,7 @@ void SubtitlePanel::content_selection_changed () { film_content_changed (FFmpegContentProperty::SUBTITLE_STREAMS); - film_content_changed (SubtitleContentProperty::SUBTITLE_OFFSET); + film_content_changed (SubtitleContentProperty::SUBTITLE_X_OFFSET); + film_content_changed (SubtitleContentProperty::SUBTITLE_Y_OFFSET); film_content_changed (SubtitleContentProperty::SUBTITLE_SCALE); } diff --git a/src/wx/subtitle_panel.h b/src/wx/subtitle_panel.h index 19df26436..20d7c40c2 100644 --- a/src/wx/subtitle_panel.h +++ b/src/wx/subtitle_panel.h @@ -33,14 +33,16 @@ public: private: void with_subtitles_toggled (); - void offset_changed (); + void x_offset_changed (); + void y_offset_changed (); void scale_changed (); void stream_changed (); void setup_sensitivity (); wxCheckBox* _with_subtitles; - wxSpinCtrl* _offset; + wxSpinCtrl* _x_offset; + wxSpinCtrl* _y_offset; wxSpinCtrl* _scale; wxChoice* _stream; }; |
