Extract examine_subtitle_nodes into its own method.
[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 #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 (boost::shared_ptr<cxml::Document> xml, std::list<boost::shared_ptr<FontNode> > font_nodes);
88         void subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Standard standard) const;
89
90         /** All our subtitles, in no particular order */
91         std::list<SubtitleString> _subtitles;
92
93         class Font
94         {
95         public:
96                 Font (std::string load_id_, std::string uuid_, boost::filesystem::path file_)
97                         : load_id (load_id_)
98                         , uuid (uuid_)
99                         , data (file_)
100                         , file (file_)
101                 {}
102
103                 Font (std::string load_id_, std::string uuid_, Data data_)
104                         : load_id (load_id_)
105                         , uuid (uuid_)
106                         , data (data_)
107                 {}
108
109                 std::string load_id;
110                 std::string uuid;
111                 Data data;
112                 /** .ttf file that this data was last written to, if applicable */
113                 mutable boost::optional<boost::filesystem::path> file;
114         };
115
116         std::list<Font> _fonts;
117
118 private:
119         /** @struct ParseState
120          *  @brief  A struct to hold state when parsing a subtitle XML file.
121          */
122         struct ParseState {
123                 std::list<boost::shared_ptr<FontNode> > font_nodes;
124                 std::list<boost::shared_ptr<TextNode> > text_nodes;
125                 std::list<boost::shared_ptr<SubtitleNode> > subtitle_nodes;
126         };
127
128         void maybe_add_subtitle (std::string text, ParseState const & parse_state);
129
130         void examine_font_nodes (
131                 boost::shared_ptr<const cxml::Node> xml,
132                 std::list<boost::shared_ptr<FontNode> > const & font_nodes,
133                 ParseState& parse_state
134                 );
135
136         void examine_text_nodes (
137                 boost::shared_ptr<const cxml::Node> xml,
138                 std::list<boost::shared_ptr<TextNode> > const & text_nodes,
139                 ParseState& parse_state
140                 );
141
142         void examine_subtitle_nodes (
143                 boost::shared_ptr<const cxml::Node> xml,
144                 std::list<boost::shared_ptr<SubtitleNode> > const & subtitle_nodes,
145                 ParseState& parse_state
146                 );
147 };
148
149 }
150
151 #endif