8f0c48abb69b254f7106d0102d99196b5d096061
[libdcp.git] / src / subtitle_asset.cc
1 /*
2     Copyright (C) 2012 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 "subtitle_asset.h"
21
22 using namespace std;
23 using namespace boost;
24 using namespace libdcp;
25
26 SubtitleAsset::SubtitleAsset (string directory, string xml)
27         : Asset (directory, xml)
28         , XMLFile (path().string(), "DCSubtitle")
29 {
30         _subtitle_id = string_node ("SubtitleID");
31         _movie_title = string_node ("MovieTitle");
32         _reel_number = int64_node ("ReelNumber");
33         _language = string_node ("Language");
34
35         ignore_node ("LoadFont");
36
37         list<shared_ptr<FontNode> > font_nodes = sub_nodes<FontNode> ("Font");
38         list<shared_ptr<LoadFontNode> > load_font_nodes = sub_nodes<LoadFontNode> ("LoadFont");
39
40         /* Now make Subtitle objects to represent the raw XML nodes
41            in a sane way.
42         */
43
44         for (list<shared_ptr<FontNode> >::iterator i = font_nodes.begin(); i != font_nodes.end(); ++i) {
45                 for (list<shared_ptr<SubtitleNode> >::iterator j = (*i)->subtitle_nodes.begin(); j != (*i)->subtitle_nodes.end(); ++j) {
46                         for (list<shared_ptr<TextNode> >::iterator k = (*j)->text_nodes.begin(); k != (*j)->text_nodes.end(); ++k) {
47                                 _subtitles.push_back (
48                                         shared_ptr<Subtitle> (
49                                                 new Subtitle (
50                                                         font_id_to_name ((*i)->id, load_font_nodes),
51                                                         (*i)->size,
52                                                         (*j)->in,
53                                                         (*j)->out,
54                                                         (*k)->v_position,
55                                                         (*k)->text
56                                                         )
57                                                 )
58                                         );
59                         }
60                 }
61         }
62 }
63
64 FontNode::FontNode (xmlpp::Node const * node)
65         : XMLNode (node)
66 {
67         id = string_attribute ("Id");
68         size = int64_attribute ("Size");
69         subtitle_nodes = sub_nodes<SubtitleNode> ("Subtitle");
70 }
71
72 LoadFontNode::LoadFontNode (xmlpp::Node const * node)
73         : XMLNode (node)
74 {
75         id = string_attribute ("Id");
76         uri = string_attribute ("URI");
77 }
78         
79
80 SubtitleNode::SubtitleNode (xmlpp::Node const * node)
81         : XMLNode (node)
82 {
83         in = time_attribute ("TimeIn");
84         out = time_attribute ("TimeOut");
85         text_nodes = sub_nodes<TextNode> ("Text");
86 }
87
88 TextNode::TextNode (xmlpp::Node const * node)
89         : XMLNode (node)
90 {
91         text = content ();
92         v_position = float_attribute ("VPosition");
93 }
94
95 list<shared_ptr<Subtitle> >
96 SubtitleAsset::subtitles_at (Time t) const
97 {
98         list<shared_ptr<Subtitle> > s;
99         for (list<shared_ptr<Subtitle> >::const_iterator i = _subtitles.begin(); i != _subtitles.end(); ++i) {
100                 if ((*i)->in() <= t && t <= (*i)->out ()) {
101                         s.push_back (*i);
102                 }
103         }
104
105         return s;
106 }
107
108 std::string
109 SubtitleAsset::font_id_to_name (string id, list<shared_ptr<LoadFontNode> > const & load_font_nodes) const
110 {
111         list<shared_ptr<LoadFontNode> >::const_iterator i = load_font_nodes.begin();
112         while (i != load_font_nodes.end() && (*i)->id != id) {
113                 ++i;
114         }
115
116         if (i == load_font_nodes.end ()) {
117                 return "";
118         }
119
120         if ((*i)->uri == "arial.ttf") {
121                 return "Arial";
122         }
123
124         return "";
125 }
126
127 Subtitle::Subtitle (
128         std::string font,
129         int size,
130         Time in,
131         Time out,
132         float v_position,
133         std::string text
134         )
135         : _font (font)
136         , _size (size)
137         , _in (in)
138         , _out (out)
139         , _v_position (v_position)
140         , _text (text)
141 {
142
143 }
144
145 int
146 Subtitle::size_in_pixels (int screen_height) const
147 {
148         /* Size in the subtitle file is given in points as if the screen
149            height is 11 inches, so a 72pt font would be 1/11th of the screen
150            height.
151         */
152         
153         return _size * screen_height / (11 * 72);
154 }