More licence fixups.
[libdcp.git] / src / subtitle_asset.h
1 /*
2     Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
3
4     This file is part of libdcp.
5
6     libdcp is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     libdcp is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with libdcp.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifndef LIBDCP_SUBTITLE_ASSET_H
21 #define LIBDCP_SUBTITLE_ASSET_H
22
23 #include "asset.h"
24 #include "dcp_time.h"
25 #include "subtitle_string.h"
26 #include "data.h"
27 #include <libcxml/cxml.h>
28 #include <boost/shared_array.hpp>
29 #include <map>
30
31 namespace xmlpp {
32         class Element;
33 }
34
35 struct interop_dcp_font_test;
36 struct smpte_dcp_font_test;
37
38 namespace dcp
39 {
40
41 class SubtitleString;
42 class FontNode;
43 class TextNode;
44 class SubtitleNode;
45 class LoadFontNode;
46
47 /** @class SubtitleAsset
48  *  @brief A parent for classes representing a file containing subtitles.
49  *
50  *  This class holds a list of SubtitleString objects which it can extract
51  *  from the appropriate part of either an Interop or SMPTE XML file.
52  *  Its subclasses InteropSubtitleAsset and SMPTESubtitleAsset handle the
53  *  differences between the two types.
54  */
55 class SubtitleAsset : public Asset
56 {
57 public:
58         SubtitleAsset ();
59         SubtitleAsset (boost::filesystem::path file);
60
61         bool equals (
62                 boost::shared_ptr<const Asset>,
63                 EqualityOptions,
64                 NoteHandler note
65                 ) const;
66
67         std::list<SubtitleString> subtitles_during (Time from, Time to, bool starting) const;
68         std::list<SubtitleString> const & subtitles () const {
69                 return _subtitles;
70         }
71
72         virtual void add (SubtitleString);
73         virtual void add_font (std::string id, boost::filesystem::path file) = 0;
74         std::map<std::string, Data> fonts_with_load_ids () const;
75
76         virtual void write (boost::filesystem::path) const = 0;
77         virtual std::string xml_as_string () const = 0;
78
79         Time latest_subtitle_out () const;
80
81         virtual std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const = 0;
82
83 protected:
84         friend struct ::interop_dcp_font_test;
85         friend struct ::smpte_dcp_font_test;
86
87         void parse_subtitles (
88                 boost::shared_ptr<cxml::Document> xml,
89                 std::list<boost::shared_ptr<FontNode> > font_nodes,
90                 std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes
91                 );
92
93         void subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Standard standard) const;
94
95         /** All our subtitles, in no particular order */
96         std::list<SubtitleString> _subtitles;
97
98         class Font
99         {
100         public:
101                 Font (std::string load_id_, std::string uuid_, boost::filesystem::path file_)
102                         : load_id (load_id_)
103                         , uuid (uuid_)
104                         , data (file_)
105                         , file (file_)
106                 {}
107
108                 Font (std::string load_id_, std::string uuid_, Data data_)
109                         : load_id (load_id_)
110                         , uuid (uuid_)
111                         , data (data_)
112                 {}
113
114                 std::string load_id;
115                 std::string uuid;
116                 Data data;
117                 /** .ttf file that this data was last written to, if applicable */
118                 mutable boost::optional<boost::filesystem::path> file;
119         };
120
121         std::list<Font> _fonts;
122
123 private:
124         /** @struct ParseState
125          *  @brief  A struct to hold state when parsing a subtitle XML file.
126          */
127         struct ParseState {
128                 std::list<boost::shared_ptr<FontNode> > font_nodes;
129                 std::list<boost::shared_ptr<TextNode> > text_nodes;
130                 std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes;
131         };
132
133         void maybe_add_subtitle (std::string text, ParseState const & parse_state);
134
135         void examine_nodes (
136                 boost::shared_ptr<const cxml::Node> xml,
137                 std::list<boost::shared_ptr<FontNode> > const & font_nodes,
138                 ParseState& parse_state
139                 );
140
141         void examine_nodes (
142                 boost::shared_ptr<const cxml::Node> xml,
143                 std::list<boost::shared_ptr<TextNode> > const & text_nodes,
144                 ParseState& parse_state
145                 );
146
147         void examine_nodes (
148                 boost::shared_ptr<const cxml::Node> xml,
149                 std::list<boost::shared_ptr<SubtitleNode> > const & subtitle_nodes,
150                 ParseState& parse_state
151                 );
152 };
153
154 }
155
156 #endif