Allow separate X and Y scale for subtitles.
[dcpomatic.git] / src / lib / subtitle_content.cc
1 /*
2     Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include <libcxml/cxml.h>
21 #include <libdcp/raw_convert.h>
22 #include "subtitle_content.h"
23 #include "util.h"
24 #include "exceptions.h"
25
26 #include "i18n.h"
27
28 using std::string;
29 using std::vector;
30 using boost::shared_ptr;
31 using boost::dynamic_pointer_cast;
32 using libdcp::raw_convert;
33
34 int const SubtitleContentProperty::SUBTITLE_X_OFFSET = 500;
35 int const SubtitleContentProperty::SUBTITLE_Y_OFFSET = 501;
36 int const SubtitleContentProperty::SUBTITLE_X_SCALE = 502;
37 int const SubtitleContentProperty::SUBTITLE_Y_SCALE = 503;
38
39 SubtitleContent::SubtitleContent (shared_ptr<const Film> f, boost::filesystem::path p)
40         : Content (f, p)
41         , _subtitle_x_offset (0)
42         , _subtitle_y_offset (0)
43         , _subtitle_x_scale (1)
44         , _subtitle_y_scale (1)
45 {
46
47 }
48
49 SubtitleContent::SubtitleContent (shared_ptr<const Film> f, shared_ptr<const cxml::Node> node, int version)
50         : Content (f, node)
51         , _subtitle_x_offset (0)
52         , _subtitle_y_offset (0)
53         , _subtitle_x_scale (1)
54         , _subtitle_y_scale (1)
55 {
56         if (version >= 7) {
57                 _subtitle_x_offset = node->number_child<float> ("SubtitleXOffset");
58                 _subtitle_y_offset = node->number_child<float> ("SubtitleYOffset");
59         } else {
60                 _subtitle_y_offset = node->number_child<float> ("SubtitleOffset");
61         }
62
63         if (version >= 10) {
64                 _subtitle_x_scale = node->number_child<float> ("SubtitleXScale");
65                 _subtitle_y_scale = node->number_child<float> ("SubtitleYScale");
66         } else {
67                 _subtitle_x_scale = _subtitle_y_scale = node->number_child<float> ("SubtitleScale");
68         }
69 }
70
71 SubtitleContent::SubtitleContent (shared_ptr<const Film> f, vector<shared_ptr<Content> > c)
72         : Content (f, c)
73 {
74         shared_ptr<SubtitleContent> ref = dynamic_pointer_cast<SubtitleContent> (c[0]);
75         assert (ref);
76         
77         for (size_t i = 0; i < c.size(); ++i) {
78                 shared_ptr<SubtitleContent> sc = dynamic_pointer_cast<SubtitleContent> (c[i]);
79
80                 if (sc->subtitle_x_offset() != ref->subtitle_x_offset()) {
81                         throw JoinError (_("Content to be joined must have the same subtitle X offset."));
82                 }
83                 
84                 if (sc->subtitle_y_offset() != ref->subtitle_y_offset()) {
85                         throw JoinError (_("Content to be joined must have the same subtitle Y offset."));
86                 }
87
88                 if (sc->subtitle_x_scale() != ref->subtitle_x_scale()) {
89                         throw JoinError (_("Content to be joined must have the same subtitle X scale."));
90                 }
91
92                 if (sc->subtitle_y_scale() != ref->subtitle_y_scale()) {
93                         throw JoinError (_("Content to be joined must have the same subtitle Y scale."));
94                 }
95         }
96
97         _subtitle_x_offset = ref->subtitle_x_offset ();
98         _subtitle_y_offset = ref->subtitle_y_offset ();
99         _subtitle_x_scale = ref->subtitle_x_scale ();
100         _subtitle_y_scale = ref->subtitle_y_scale ();
101 }
102
103 void
104 SubtitleContent::as_xml (xmlpp::Node* root) const
105 {
106         root->add_child("SubtitleXOffset")->add_child_text (raw_convert<string> (_subtitle_x_offset));
107         root->add_child("SubtitleYOffset")->add_child_text (raw_convert<string> (_subtitle_y_offset));
108         root->add_child("SubtitleXScale")->add_child_text (raw_convert<string> (_subtitle_x_scale));
109         root->add_child("SubtitleYScale")->add_child_text (raw_convert<string> (_subtitle_y_scale));
110 }
111
112 void
113 SubtitleContent::set_subtitle_x_offset (double o)
114 {
115         {
116                 boost::mutex::scoped_lock lm (_mutex);
117                 _subtitle_x_offset = o;
118         }
119         signal_changed (SubtitleContentProperty::SUBTITLE_X_OFFSET);
120 }
121
122 void
123 SubtitleContent::set_subtitle_y_offset (double o)
124 {
125         {
126                 boost::mutex::scoped_lock lm (_mutex);
127                 _subtitle_y_offset = o;
128         }
129         signal_changed (SubtitleContentProperty::SUBTITLE_Y_OFFSET);
130 }
131
132 void
133 SubtitleContent::set_subtitle_x_scale (double s)
134 {
135         {
136                 boost::mutex::scoped_lock lm (_mutex);
137                 _subtitle_x_scale = s;
138         }
139         signal_changed (SubtitleContentProperty::SUBTITLE_X_SCALE);
140 }
141
142 void
143 SubtitleContent::set_subtitle_y_scale (double s)
144 {
145         {
146                 boost::mutex::scoped_lock lm (_mutex);
147                 _subtitle_y_scale = s;
148         }
149         signal_changed (SubtitleContentProperty::SUBTITLE_Y_SCALE);
150 }