Merge.
[libdcp.git] / src / subtitle_asset.h
1 /*
2     Copyright (C) 2012-2015 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 #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
30 namespace xmlpp {
31         class Element;
32 }
33
34 struct interop_dcp_font_test;
35 struct smpte_dcp_font_test;
36
37 namespace dcp
38 {
39
40 class SubtitleString;
41 class FontNode;
42 class TextNode;
43 class SubtitleNode;
44 class LoadFontNode;
45
46 /** @class SubtitleAsset
47  *  @brief A parent for classes representing a file containing subtitles.
48  *
49  *  This class holds a list of SubtitleString objects which it can extract
50  *  from the appropriate part of either an Interop or SMPTE XML file.
51  *  Its subclasses InteropSubtitleAsset and SMPTESubtitleAsset handle the
52  *  differences between the two types.
53  */
54 class SubtitleAsset : public Asset
55 {
56 public:
57         SubtitleAsset ();
58         SubtitleAsset (boost::filesystem::path file);
59
60         bool equals (
61                 boost::shared_ptr<const Asset>,
62                 EqualityOptions,
63                 NoteHandler note
64                 ) const;
65
66         std::list<SubtitleString> subtitles_during (Time from, Time to) const;
67         std::list<SubtitleString> const & subtitles () const {
68                 return _subtitles;
69         }
70
71         void add (SubtitleString);
72         virtual void add_font (std::string id, boost::filesystem::path file) = 0;
73         std::map<std::string, Data> fonts_with_load_ids () const;
74
75         virtual void write (boost::filesystem::path) const = 0;
76         virtual Glib::ustring xml_as_string () const = 0;
77
78         Time latest_subtitle_out () const;
79
80         virtual std::list<boost::shared_ptr<LoadFontNode> > load_font_nodes () const = 0;
81
82 protected:
83         friend struct ::interop_dcp_font_test;
84         friend struct ::smpte_dcp_font_test;
85
86         void parse_subtitles (boost::shared_ptr<cxml::Document> xml, std::list<boost::shared_ptr<FontNode> > font_nodes);
87         void subtitles_as_xml (xmlpp::Element* root, int time_code_rate, std::string xmlns) const;
88
89         /** All our subtitles, in no particular order */
90         std::list<SubtitleString> _subtitles;
91
92         class Font
93         {
94         public:
95                 Font (std::string load_id_, std::string uuid_, boost::filesystem::path file_)
96                         : load_id (load_id_)
97                         , uuid (uuid_)
98                         , data (file_)
99                         , file (file_)
100                 {}
101
102                 Font (std::string load_id_, std::string uuid_, Data data_)
103                         : load_id (load_id_)
104                         , uuid (uuid_)
105                         , data (data_)
106                 {}
107
108                 std::string load_id;
109                 std::string uuid;
110                 Data data;
111                 /** .ttf file that this data was last written to, if applicable */
112                 mutable boost::optional<boost::filesystem::path> file;
113         };
114
115         std::list<Font> _fonts;
116
117 private:
118         /** @struct ParseState
119          *  @brief  A struct to hold state when parsing a subtitle XML file.
120          */
121         struct ParseState {
122                 std::list<boost::shared_ptr<FontNode> > font_nodes;
123                 std::list<boost::shared_ptr<TextNode> > text_nodes;
124                 std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes;
125         };
126
127         void maybe_add_subtitle (std::string text, ParseState const & parse_state);
128
129         void examine_font_nodes (
130                 boost::shared_ptr<const cxml::Node> xml,
131                 std::list<boost::shared_ptr<FontNode> > const & font_nodes,
132                 ParseState& parse_state
133                 );
134
135         void examine_text_nodes (
136                 boost::shared_ptr<const cxml::Node> xml,
137                 std::list<boost::shared_ptr<TextNode> > const & text_nodes,
138                 ParseState& parse_state
139                 );
140 };
141
142 }
143
144 #endif