Move some tests from write_subtitle_test into interop_subtitle_test.
[libdcp.git] / test / interop_subtitle_test.cc
1 /*
2     Copyright (C) 2012-202]1 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     In addition, as a special exception, the copyright holders give
20     permission to link the code of portions of this program with the
21     OpenSSL library under certain conditions as described in each
22     individual source file, and distribute linked combinations
23     including the two.
24
25     You must obey the GNU General Public License in all respects
26     for all of the code used other than OpenSSL.  If you modify
27     file(s) with this exception, you may extend this exception to your
28     version of the file(s), but you are not obligated to do so.  If you
29     do not wish to do so, delete this exception statement from your
30     version.  If you delete this exception statement from all source
31     files in the program, then also delete it here.
32 */
33
34
35 #include "interop_subtitle_asset.h"
36 #include "interop_load_font_node.h"
37 #include "reel_interop_subtitle_asset.h"
38 #include "subtitle_string.h"
39 #include "subtitle_image.h"
40 #include "test.h"
41 #include <boost/test/unit_test.hpp>
42 #include <iostream>
43
44
45 using std::dynamic_pointer_cast;
46 using std::list;
47 using std::make_shared;
48 using std::shared_ptr;
49 using std::string;
50 using std::vector;
51
52
53 /** Load some subtitle content from Interop XML and check that it is read correctly */
54 BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
55 {
56         dcp::InteropSubtitleAsset subs ("test/data/subs1.xml");
57
58         BOOST_CHECK_EQUAL (subs.id(), "cab5c268-222b-41d2-88ae-6d6999441b17");
59         BOOST_CHECK_EQUAL (subs.movie_title(), "Movie Title");
60         BOOST_CHECK_EQUAL (subs.reel_number(), "1");
61         BOOST_CHECK_EQUAL (subs.language(), "French");
62
63         auto lfn = subs.load_font_nodes ();
64         BOOST_REQUIRE_EQUAL (lfn.size(), 1);
65         shared_ptr<dcp::InteropLoadFontNode> interop_lfn = dynamic_pointer_cast<dcp::InteropLoadFontNode> (lfn.front ());
66         BOOST_REQUIRE (interop_lfn);
67         BOOST_CHECK_EQUAL (interop_lfn->id, "theFontId");
68         BOOST_CHECK_EQUAL (interop_lfn->uri, "arial.ttf");
69
70         auto s = subs.subtitles_during (dcp::Time (0, 0, 6, 1, 250), dcp::Time (0, 0, 6, 2, 250), false);
71         BOOST_REQUIRE_EQUAL (s.size(), 1);
72         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
73         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
74                                    string ("theFontId"),
75                                    false,
76                                    false,
77                                    false,
78                                    dcp::Colour (255, 255, 255),
79                                    39,
80                                    1.0,
81                                    dcp::Time (0, 0, 5, 198, 250),
82                                    dcp::Time (0, 0, 7, 115, 250),
83                                    0,
84                                    dcp::HAlign::CENTER,
85                                    0.15,
86                                    dcp::VAlign::BOTTOM,
87                                    dcp::Direction::LTR,
88                                    "My jacket was Idi Amin's",
89                                    dcp::Effect::BORDER,
90                                    dcp::Colour (0, 0, 0),
91                                    dcp::Time (0, 0, 0, 1, 250),
92                                    dcp::Time (0, 0, 0, 1, 250)
93                                    ));
94
95         s = subs.subtitles_during (dcp::Time (0, 0, 7, 190, 250), dcp::Time (0, 0, 7, 191, 250), false);
96         BOOST_REQUIRE_EQUAL (s.size(), 2);
97         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
98         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
99                                    string ("theFontId"),
100                                    true,
101                                    false,
102                                    false,
103                                    dcp::Colour (255, 255, 255),
104                                    39,
105                                    1.0,
106                                    dcp::Time (0, 0, 7, 177, 250),
107                                    dcp::Time (0, 0, 11, 31, 250),
108                                    0,
109                                    dcp::HAlign::CENTER,
110                                    0.21,
111                                    dcp::VAlign::BOTTOM,
112                                    dcp::Direction::LTR,
113                                    "My corset was H.M. The Queen's",
114                                    dcp::Effect::BORDER,
115                                    dcp::Colour (0, 0, 0),
116                                    dcp::Time (0, 0, 0, 1, 250),
117                                    dcp::Time (0, 0, 0, 1, 250)
118                                    ));
119         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
120         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
121                                    string ("theFontId"),
122                                    false,
123                                    false,
124                                    false,
125                                    dcp::Colour (255, 255, 255),
126                                    39,
127                                    1.0,
128                                    dcp::Time (0, 0, 7, 177, 250),
129                                    dcp::Time (0, 0, 11, 31, 250),
130                                    0,
131                                    dcp::HAlign::CENTER,
132                                    0.15,
133                                    dcp::VAlign::BOTTOM,
134                                    dcp::Direction::LTR,
135                                    "My large wonderbra",
136                                    dcp::Effect::BORDER,
137                                    dcp::Colour (0, 0, 0),
138                                    dcp::Time (0, 0, 0, 1, 250),
139                                    dcp::Time (0, 0, 0, 1, 250)
140                                    ));
141
142         s = subs.subtitles_during (dcp::Time (0, 0, 11, 95, 250), dcp::Time (0, 0, 11, 96, 250), false);
143         BOOST_REQUIRE_EQUAL (s.size(), 1);
144         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
145         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
146                                    string ("theFontId"),
147                                    false,
148                                    false,
149                                    false,
150                                    dcp::Colour (255, 255, 255),
151                                    39,
152                                    1.0,
153                                    dcp::Time (0, 0, 11, 94, 250),
154                                    dcp::Time (0, 0, 13, 63, 250),
155                                    0,
156                                    dcp::HAlign::CENTER,
157                                    0.15,
158                                    dcp::VAlign::BOTTOM,
159                                    dcp::Direction::LTR,
160                                    "Once belonged to the Shah",
161                                    dcp::Effect::BORDER,
162                                    dcp::Colour (0, 0, 0),
163                                    dcp::Time (0, 0, 0, 1, 250),
164                                    dcp::Time (0, 0, 0, 1, 250)
165                                    ));
166
167         s = subs.subtitles_during (dcp::Time (0, 0, 14, 42, 250), dcp::Time (0, 0, 14, 43, 250), false);
168         BOOST_REQUIRE_EQUAL (s.size(), 1);
169         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
170         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
171                                    string ("theFontId"),
172                                    false,
173                                    true,
174                                    true,
175                                    dcp::Colour (255, 255, 255),
176                                    39,
177                                    1.0,
178                                    dcp::Time (0, 0, 13, 104, 250),
179                                    dcp::Time (0, 0, 15, 177, 250),
180                                    0,
181                                    dcp::HAlign::CENTER,
182                                    0.15,
183                                    dcp::VAlign::BOTTOM,
184                                    dcp::Direction::LTR,
185                                    "And these are Roy Hattersley's jeans",
186                                    dcp::Effect::BORDER,
187                                    dcp::Colour (0, 0, 0),
188                                    dcp::Time (0, 0, 0, 1, 250),
189                                    dcp::Time (0, 0, 0, 1, 250)
190                                    ));
191 }
192
193 /** And similarly for another one */
194 BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
195 {
196         dcp::InteropSubtitleAsset subs ("test/data/subs2.xml");
197
198         auto s = subs.subtitles_during (dcp::Time (0, 0, 42, 100, 250), dcp::Time (0, 0, 42, 101, 250), false);
199         BOOST_REQUIRE_EQUAL (s.size(), 2);
200         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
201         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
202                                    string ("theFont"),
203                                    true,
204                                    false,
205                                    false,
206                                    dcp::Colour (255, 255, 255),
207                                    42,
208                                    1.0,
209                                    dcp::Time (0, 0, 41, 62, 250),
210                                    dcp::Time (0, 0, 43, 52, 250),
211                                    0,
212                                    dcp::HAlign::CENTER,
213                                    0.89,
214                                    dcp::VAlign::TOP,
215                                    dcp::Direction::LTR,
216                                    "At afternoon tea with John Peel",
217                                    dcp::Effect::BORDER,
218                                    dcp::Colour (0, 0, 0),
219                                    dcp::Time (0, 0, 0, 0, 250),
220                                    dcp::Time (0, 0, 0, 0, 250)
221                                    ));
222         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
223         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
224                                    string ("theFont"),
225                                    true,
226                                    false,
227                                    false,
228                                    dcp::Colour (255, 255, 255),
229                                    42,
230                                    1.0,
231                                    dcp::Time (0, 0, 41, 62, 250),
232                                    dcp::Time (0, 0, 43, 52, 250),
233                                    0,
234                                    dcp::HAlign::CENTER,
235                                    0.95,
236                                    dcp::VAlign::TOP,
237                                    dcp::Direction::LTR,
238                                    "I enquired if his accent was real",
239                                    dcp::Effect::BORDER,
240                                    dcp::Colour (0, 0, 0),
241                                    dcp::Time (0, 0, 0, 0, 250),
242                                    dcp::Time (0, 0, 0, 0, 250)
243                                    ));
244
245         s = subs.subtitles_during (dcp::Time (0, 0, 50, 50, 250), dcp::Time (0, 0, 50, 51, 250), false);
246         BOOST_REQUIRE_EQUAL (s.size(), 2);
247         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
248         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
249                                    string ("theFont"),
250                                    true,
251                                    false,
252                                    false,
253                                    dcp::Colour (255, 255, 255),
254                                    42,
255                                    1.0,
256                                    dcp::Time (0, 0, 50, 42, 250),
257                                    dcp::Time (0, 0, 52, 21, 250),
258                                    0,
259                                    dcp::HAlign::CENTER,
260                                    0.89,
261                                    dcp::VAlign::TOP,
262                                    dcp::Direction::LTR,
263                                    "He said \"out of the house",
264                                    dcp::Effect::BORDER,
265                                    dcp::Colour (0, 0, 0),
266                                    dcp::Time (0, 0, 0, 0, 250),
267                                    dcp::Time (0, 0, 0, 0, 250)
268                                    ));
269         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
270         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
271                                    string ("theFont"),
272                                    true,
273                                    false,
274                                    false,
275                                    dcp::Colour (255, 255, 255),
276                                    42,
277                                    1.0,
278                                    dcp::Time (0, 0, 50, 42, 250),
279                                    dcp::Time (0, 0, 52, 21, 250),
280                                    0,
281                                    dcp::HAlign::CENTER,
282                                    0.95,
283                                    dcp::VAlign::TOP,
284                                    dcp::Direction::LTR,
285                                    "I'm incredibly scouse",
286                                    dcp::Effect::BORDER,
287                                    dcp::Colour (0, 0, 0),
288                                    dcp::Time (0, 0, 0, 0, 250),
289                                    dcp::Time (0, 0, 0, 0, 250)
290                                    ));
291
292         s = subs.subtitles_during (dcp::Time (0, 1, 2, 300, 250), dcp::Time (0, 1, 2, 301, 250), false);
293         BOOST_REQUIRE_EQUAL (s.size(), 2);
294         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
295         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
296                                    string("theFont"),
297                                    true,
298                                    false,
299                                    false,
300                                    dcp::Colour(255, 255, 255),
301                                    42,
302                                    1.0,
303                                    dcp::Time(0, 1, 2, 208, 250),
304                                    dcp::Time(0, 1, 4, 10, 250),
305                                    0,
306                                    dcp::HAlign::CENTER,
307                                    0.89,
308                                    dcp::VAlign::TOP,
309                                    dcp::Direction::LTR,
310                                    "At home it depends how I feel.\"",
311                                    dcp::Effect::BORDER,
312                                    dcp::Colour(0, 0, 0),
313                                    dcp::Time(0, 0, 0, 0, 250),
314                                    dcp::Time(0, 0, 0, 0, 250)
315                                    ));
316         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
317         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
318                                    string ("theFont"),
319                                    true,
320                                    false,
321                                    false,
322                                    dcp::Colour(255, 255, 255),
323                                    42,
324                                    1.0,
325                                    dcp::Time(0, 1, 2, 208, 250),
326                                    dcp::Time(0, 1, 4, 10, 250),
327                                    0,
328                                    dcp::HAlign::CENTER,
329                                    0.95,
330                                    dcp::VAlign::TOP,
331                                    dcp::Direction::LTR,
332                                    "I spent a long weekend in Brighton",
333                                    dcp::Effect::BORDER,
334                                    dcp::Colour(0, 0, 0),
335                                    dcp::Time(0, 0, 0, 0, 250),
336                                    dcp::Time(0, 0, 0, 0, 250)
337                                    ));
338
339         s = subs.subtitles_during (dcp::Time (0, 1, 15, 50, 250), dcp::Time (0, 1, 15, 51, 250), false);
340         BOOST_REQUIRE_EQUAL (s.size(), 2);
341         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
342         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
343                                    string ("theFont"),
344                                    true,
345                                    false,
346                                    false,
347                                    dcp::Colour(255, 255, 255),
348                                    42,
349                                    1.0,
350                                    dcp::Time(0, 1, 15, 42, 250),
351                                    dcp::Time(0, 1, 16, 42, 250),
352                                    0,
353                                    dcp::HAlign::CENTER,
354                                    0.89,
355                                    dcp::VAlign::TOP,
356                                    dcp::Direction::RTL,
357                                    "With the legendary Miss Enid Blyton",
358                                    dcp::Effect::BORDER,
359                                    dcp::Colour(0, 0, 0),
360                                    dcp::Time(0, 0, 0, 0, 250),
361                                    dcp::Time(0, 0, 0, 0, 250)
362                                    ));
363         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
364         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
365                                    string ("theFont"),
366                                    true,
367                                    false,
368                                    false,
369                                    dcp::Colour(255, 255, 255),
370                                    42,
371                                    1.0,
372                                    dcp::Time(0, 1, 15, 42, 250),
373                                    dcp::Time(0, 1, 16, 42, 250),
374                                    0,
375                                    dcp::HAlign::CENTER,
376                                    0.95,
377                                    dcp::VAlign::TOP,
378                                    dcp::Direction::TTB,
379                                    "She said \"you be Noddy",
380                                    dcp::Effect::BORDER,
381                                    dcp::Colour(0, 0, 0),
382                                    dcp::Time(0, 0, 0, 0, 250),
383                                    dcp::Time(0, 0, 0, 0, 250)
384                                    ));
385
386         s = subs.subtitles_during (dcp::Time (0, 1, 27, 200, 250), dcp::Time (0, 1, 27, 201, 250), false);
387         BOOST_REQUIRE_EQUAL (s.size(), 2);
388         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
389         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
390                                    string ("theFont"),
391                                    true,
392                                    false,
393                                    false,
394                                    dcp::Colour(255, 255, 255),
395                                    42,
396                                    1.0,
397                                    dcp::Time(0, 1, 27, 115, 250),
398                                    dcp::Time(0, 1, 28, 208, 250),
399                                    0,
400                                    dcp::HAlign::CENTER,
401                                    0.89,
402                                    dcp::VAlign::TOP,
403                                    dcp::Direction::BTT,
404                                    "That curious creature the Sphinx",
405                                    dcp::Effect::BORDER,
406                                    dcp::Colour(0, 0, 0),
407                                    dcp::Time(0, 0, 0, 0, 250),
408                                    dcp::Time(0, 0, 0, 0, 250)
409                                    ));
410         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
411         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
412                                    string ("theFont"),
413                                    true,
414                                    false,
415                                    false,
416                                    dcp::Colour(255, 255, 255),
417                                    42,
418                                    1.0,
419                                    dcp::Time(0, 1, 27, 115, 250),
420                                    dcp::Time(0, 1, 28, 208, 250),
421                                    0,
422                                    dcp::HAlign::CENTER,
423                                    0.95,
424                                    dcp::VAlign::TOP,
425                                    dcp::Direction::LTR,
426                                    "Is smarter than anyone thinks",
427                                    dcp::Effect::BORDER,
428                                    dcp::Colour(0, 0, 0),
429                                    dcp::Time(0, 0, 0, 0, 250),
430                                    dcp::Time(0, 0, 0, 0, 250)
431                                    ));
432
433         s = subs.subtitles_during (dcp::Time (0, 1, 42, 300, 250), dcp::Time (0, 1, 42, 301, 250), false);
434         BOOST_REQUIRE_EQUAL (s.size(), 2);
435         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
436         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
437                                    string ("theFont"),
438                                    false,
439                                    false,
440                                    false,
441                                    dcp::Colour (255, 255, 255),
442                                    42,
443                                    1.0,
444                                    dcp::Time (0, 1, 42, 229, 250),
445                                    dcp::Time (0, 1, 45, 62, 250),
446                                    0,
447                                    dcp::HAlign::CENTER,
448                                    0.89,
449                                    dcp::VAlign::TOP,
450                                    dcp::Direction::LTR,
451                                    "It sits there and smirks",
452                                    dcp::Effect::BORDER,
453                                    dcp::Colour(0, 0, 0),
454                                    dcp::Time(0, 0, 0, 0, 250),
455                                    dcp::Time(0, 0, 0, 0, 250)
456                                    ));
457         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
458         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
459                                    string ("theFont"),
460                                    false,
461                                    false,
462                                    false,
463                                    dcp::Colour (255, 255, 255),
464                                    42,
465                                    1.0,
466                                    dcp::Time (0, 1, 42, 229, 250),
467                                    dcp::Time (0, 1, 45, 62, 250),
468                                    0,
469                                    dcp::HAlign::CENTER,
470                                    0.95,
471                                    dcp::VAlign::TOP,
472                                    dcp::Direction::LTR,
473                                    "And you don't think it works",
474                                    dcp::Effect::BORDER,
475                                    dcp::Colour(0, 0, 0),
476                                    dcp::Time(0, 0, 0, 0, 250),
477                                    dcp::Time(0, 0, 0, 0, 250)
478                                    ));
479
480         s = subs.subtitles_during (dcp::Time (0, 1, 45, 200, 250), dcp::Time (0, 1, 45, 201, 250), false);
481         BOOST_REQUIRE_EQUAL (s.size(), 2);
482         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
483         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
484                                    string("theFont"),
485                                    false,
486                                    false,
487                                    false,
488                                    dcp::Colour(255, 255, 255),
489                                    42,
490                                    1.0,
491                                    dcp::Time(0, 1, 45, 146, 250),
492                                    dcp::Time(0, 1, 47, 94, 250),
493                                    0,
494                                    dcp::HAlign::CENTER,
495                                    0.89,
496                                    dcp::VAlign::TOP,
497                                    dcp::Direction::LTR,
498                                    "Then when you're not looking, it winks.",
499                                    dcp::Effect::BORDER,
500                                    dcp::Colour(0, 0, 0),
501                                    dcp::Time(0, 0, 0, 0, 250),
502                                    dcp::Time(0, 0, 0, 0, 250)
503                                    ));
504         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
505         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
506                                    string ("theFont"),
507                                    false,
508                                    false,
509                                    false,
510                                    dcp::Colour (255, 255, 255),
511                                    42,
512                                    1.0,
513                                    dcp::Time (0, 1, 45, 146, 250),
514                                    dcp::Time (0, 1, 47, 94, 250),
515                                    0,
516                                    dcp::HAlign::CENTER,
517                                    0.95,
518                                    dcp::VAlign::TOP,
519                                    dcp::Direction::LTR,
520                                    "When it snows you will find Sister Sledge",
521                                    dcp::Effect::BORDER,
522                                    dcp::Colour(0, 0, 0),
523                                    dcp::Time(0, 0, 0, 0, 250),
524                                    dcp::Time(0, 0, 0, 0, 250)
525                                    ));
526
527         s = subs.subtitles_during (dcp::Time (0, 1, 47, 249, 250), dcp::Time (0, 1, 47, 250, 250), false);
528         BOOST_REQUIRE_EQUAL (s.size(), 2);
529         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
530         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
531                                    string ("theFont"),
532                                    false,
533                                    false,
534                                    false,
535                                    dcp::Colour(255, 255, 255),
536                                    42,
537                                    1.0,
538                                    dcp::Time(0, 1, 47, 146, 250),
539                                    dcp::Time(0, 1, 48, 167, 250),
540                                    0,
541                                    dcp::HAlign::CENTER,
542                                    0.89,
543                                    dcp::VAlign::TOP,
544                                    dcp::Direction::LTR,
545                                    "Out mooning, at night, on the ledge",
546                                    dcp::Effect::BORDER,
547                                    dcp::Colour(0, 0, 0),
548                                    dcp::Time(0, 0, 0, 0, 250),
549                                    dcp::Time(0, 0, 0, 0, 250)
550                                    ));
551         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
552         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
553                                    string ("theFont"),
554                                    false,
555                                    false,
556                                    false,
557                                    dcp::Colour(255, 255, 255),
558                                    42,
559                                    1.0,
560                                    dcp::Time(0, 1, 47, 146, 250),
561                                    dcp::Time(0, 1, 48, 167, 250),
562                                    0,
563                                    dcp::HAlign::CENTER,
564                                    0.95,
565                                    dcp::VAlign::TOP,
566                                    dcp::Direction::LTR,
567                                    "One storey down",
568                                    dcp::Effect::BORDER,
569                                    dcp::Colour(0, 0, 0),
570                                    dcp::Time(0, 0, 0, 0, 250),
571                                    dcp::Time(0, 0, 0, 0, 250)
572                                    ));
573
574         s = subs.subtitles_during (dcp::Time (0, 2, 6, 210, 250), dcp::Time (0, 2, 6, 211, 250), false);
575         BOOST_REQUIRE_EQUAL (s.size(), 2);
576         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.front()));
577         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.front()), dcp::SubtitleString (
578                                    string ("theFont"),
579                                    true,
580                                    false,
581                                    false,
582                                    dcp::Colour (255, 255, 255),
583                                    42,
584                                    1.0,
585                                    dcp::Time (0, 2, 5, 208, 250),
586                                    dcp::Time (0, 2, 7, 31, 250),
587                                    0,
588                                    dcp::HAlign::CENTER,
589                                    0.89,
590                                    dcp::VAlign::TOP,
591                                    dcp::Direction::LTR,
592                                    "HELLO",
593                                    dcp::Effect::BORDER,
594                                    dcp::Colour(0, 0, 0),
595                                    dcp::Time(0, 0, 0, 0, 250),
596                                    dcp::Time(0, 0, 0, 0, 250)
597                                    ));
598         BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
599         BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
600                                    string ("theFont"),
601                                    true,
602                                    false,
603                                    false,
604                                    dcp::Colour(255, 255, 255),
605                                    42,
606                                    1.0,
607                                    dcp::Time(0, 2, 5, 208, 250),
608                                    dcp::Time(0, 2, 7, 31, 250),
609                                    0,
610                                    dcp::HAlign::CENTER,
611                                    0.95,
612                                    dcp::VAlign::TOP,
613                                    dcp::Direction::LTR,
614                                    "WORLD",
615                                    dcp::Effect::BORDER,
616                                    dcp::Colour(0, 0, 0),
617                                    dcp::Time(0, 0, 0, 0, 250),
618                                    dcp::Time(0, 0, 0, 0, 250)
619                                    ));
620 }
621
622 /** And one with bitmap subtitles */
623 BOOST_AUTO_TEST_CASE (read_interop_subtitle_test3)
624 {
625         dcp::InteropSubtitleAsset subs ("test/data/subs3.xml");
626
627         BOOST_REQUIRE_EQUAL (subs.subtitles().size(), 1);
628         auto si = dynamic_pointer_cast<const dcp::SubtitleImage>(subs.subtitles().front());
629         BOOST_REQUIRE (si);
630         BOOST_CHECK (si->png_image() == dcp::ArrayData("test/data/sub.png"));
631 }
632
633
634 /** Write some subtitle content as Interop XML and check that it is right */
635 BOOST_AUTO_TEST_CASE (write_interop_subtitle_test)
636 {
637         dcp::InteropSubtitleAsset c;
638         c.set_reel_number ("1");
639         c.set_language ("EN");
640         c.set_movie_title ("Test");
641
642         c.add (
643                 make_shared<dcp::SubtitleString>(
644                         string ("Frutiger"),
645                         false,
646                         false,
647                         false,
648                         dcp::Colour (255, 255, 255),
649                         48,
650                         1.0,
651                         dcp::Time (0, 4,  9, 22, 24),
652                         dcp::Time (0, 4, 11, 22, 24),
653                         0,
654                         dcp::HAlign::CENTER,
655                         0.8,
656                         dcp::VAlign::TOP,
657                         dcp::Direction::LTR,
658                         "Hello world",
659                         dcp::Effect::NONE,
660                         dcp::Colour (0, 0, 0),
661                         dcp::Time (0, 0, 0, 0, 24),
662                         dcp::Time (0, 0, 0, 0, 24)
663                         )
664                 );
665
666         c.add (
667                 make_shared<dcp::SubtitleString>(
668                         boost::optional<string> (),
669                         true,
670                         true,
671                         true,
672                         dcp::Colour (128, 0, 64),
673                         91,
674                         1.0,
675                         dcp::Time (5, 41,  0, 21, 24),
676                         dcp::Time (6, 12, 15, 21, 24),
677                         0,
678                         dcp::HAlign::CENTER,
679                         0.4,
680                         dcp::VAlign::BOTTOM,
681                         dcp::Direction::LTR,
682                         "What's going on",
683                         dcp::Effect::BORDER,
684                         dcp::Colour (1, 2, 3),
685                         dcp::Time (1, 2, 3, 4, 24),
686                         dcp::Time (5, 6, 7, 8, 24)
687                         )
688                 );
689
690         c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6";
691
692         check_xml (
693                 "<DCSubtitle Version=\"1.0\">"
694                   "<SubtitleID>a6c58cff-3e1e-4b38-acec-a42224475ef6</SubtitleID>"
695                   "<MovieTitle>Test</MovieTitle>"
696                   "<ReelNumber>1</ReelNumber>"
697                   "<Language>EN</Language>"
698                   "<Font AspectAdjust=\"1.0\" Color=\"FFFFFFFF\" Effect=\"none\" EffectColor=\"FF000000\" Id=\"Frutiger\" Italic=\"no\" Script=\"normal\" Size=\"48\" Underlined=\"no\" Weight=\"normal\">"
699                     "<Subtitle SpotNumber=\"1\" TimeIn=\"00:04:09:229\" TimeOut=\"00:04:11:229\" FadeUpTime=\"0\" FadeDownTime=\"0\">"
700                       "<Text VAlign=\"top\" VPosition=\"80\">Hello world</Text>"
701                     "</Subtitle>"
702                   "</Font>"
703                   "<Font AspectAdjust=\"1.0\" Color=\"FF800040\" Effect=\"border\" EffectColor=\"FF010203\" Italic=\"yes\" Script=\"normal\" Size=\"91\" Underlined=\"yes\" Weight=\"bold\">"
704                     "<Subtitle SpotNumber=\"2\" TimeIn=\"05:41:00:219\" TimeOut=\"06:12:15:219\" FadeUpTime=\"930792\" FadeDownTime=\"4591834\">"
705                       "<Text VAlign=\"bottom\" VPosition=\"40\">What's going on</Text>"
706                     "</Subtitle>"
707                   "</Font>"
708                 "</DCSubtitle>",
709                 c.xml_as_string (),
710                 vector<string>()
711                 );
712 }
713
714 /** Write some subtitle content as Interop XML and check that it is right.
715  *  This test includes some horizontal alignment.
716  */
717 BOOST_AUTO_TEST_CASE (write_interop_subtitle_test2)
718 {
719         dcp::InteropSubtitleAsset c;
720         c.set_reel_number ("1");
721         c.set_language ("EN");
722         c.set_movie_title ("Test");
723
724         c.add (
725                 make_shared<dcp::SubtitleString>(
726                         string ("Frutiger"),
727                         false,
728                         false,
729                         false,
730                         dcp::Colour (255, 255, 255),
731                         48,
732                         1.0,
733                         dcp::Time (0, 4,  9, 22, 24),
734                         dcp::Time (0, 4, 11, 22, 24),
735                         -0.2,
736                         dcp::HAlign::CENTER,
737                         0.8,
738                         dcp::VAlign::TOP,
739                         dcp::Direction::LTR,
740                         "Hello world",
741                         dcp::Effect::NONE,
742                         dcp::Colour (0, 0, 0),
743                         dcp::Time (0, 0, 0, 0, 24),
744                         dcp::Time (0, 0, 0, 0, 24)
745                         )
746                 );
747
748         c.add (
749                 make_shared<dcp::SubtitleString>(
750                         boost::optional<string>(),
751                         true,
752                         true,
753                         true,
754                         dcp::Colour (128, 0, 64),
755                         91,
756                         1.0,
757                         dcp::Time (5, 41,  0, 21, 24),
758                         dcp::Time (6, 12, 15, 21, 24),
759                         -0.2,
760                         dcp::HAlign::CENTER,
761                         0.4,
762                         dcp::VAlign::BOTTOM,
763                         dcp::Direction::LTR,
764                         "What's going on",
765                         dcp::Effect::BORDER,
766                         dcp::Colour (1, 2, 3),
767                         dcp::Time (1, 2, 3, 4, 24),
768                         dcp::Time (5, 6, 7, 8, 24)
769                         )
770                 );
771
772         c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6";
773
774         check_xml (
775                 "<DCSubtitle Version=\"1.0\">"
776                   "<SubtitleID>a6c58cff-3e1e-4b38-acec-a42224475ef6</SubtitleID>"
777                   "<MovieTitle>Test</MovieTitle>"
778                   "<ReelNumber>1</ReelNumber>"
779                   "<Language>EN</Language>"
780                   "<Font AspectAdjust=\"1.0\" Color=\"FFFFFFFF\" Effect=\"none\" EffectColor=\"FF000000\" Id=\"Frutiger\" Italic=\"no\" Script=\"normal\" Size=\"48\" Underlined=\"no\" Weight=\"normal\">"
781                     "<Subtitle SpotNumber=\"1\" TimeIn=\"00:04:09:229\" TimeOut=\"00:04:11:229\" FadeUpTime=\"0\" FadeDownTime=\"0\">"
782                       "<Text HPosition=\"-20\" VAlign=\"top\" VPosition=\"80\">Hello world</Text>"
783                     "</Subtitle>"
784                   "</Font>"
785                   "<Font AspectAdjust=\"1.0\" Color=\"FF800040\" Effect=\"border\" EffectColor=\"FF010203\" Italic=\"yes\" Script=\"normal\" Size=\"91\" Underlined=\"yes\" Weight=\"bold\">"
786                     "<Subtitle SpotNumber=\"2\" TimeIn=\"05:41:00:219\" TimeOut=\"06:12:15:219\" FadeUpTime=\"930792\" FadeDownTime=\"4591834\">"
787                       "<Text HPosition=\"-20\" VAlign=\"bottom\" VPosition=\"40\">What's going on</Text>"
788                     "</Subtitle>"
789                   "</Font>"
790                 "</DCSubtitle>",
791                 c.xml_as_string (),
792                 vector<string>()
793                 );
794 }
795
796 /* Write some subtitle content as Interop XML using bitmaps and check that it is right */
797 BOOST_AUTO_TEST_CASE (write_interop_subtitle_test3)
798 {
799         RNGFixer fix;
800
801         auto c = make_shared<dcp::InteropSubtitleAsset>();
802         c->set_reel_number ("1");
803         c->set_language ("EN");
804         c->set_movie_title ("Test");
805
806         c->add (
807                 make_shared<dcp::SubtitleImage>(
808                         dcp::ArrayData ("test/data/sub.png"),
809                         dcp::Time (0, 4,  9, 22, 24),
810                         dcp::Time (0, 4, 11, 22, 24),
811                         0,
812                         dcp::HAlign::CENTER,
813                         0.8,
814                         dcp::VAlign::TOP,
815                         dcp::Time (0, 0, 0, 0, 24),
816                         dcp::Time (0, 0, 0, 0, 24)
817                         )
818                 );
819
820         c->_id = "a6c58cff-3e1e-4b38-acec-a42224475ef6";
821         boost::filesystem::remove_all ("build/test/write_interop_subtitle_test3");
822         boost::filesystem::create_directories ("build/test/write_interop_subtitle_test3");
823         c->write ("build/test/write_interop_subtitle_test3/subs.xml");
824
825         auto reel = make_shared<dcp::Reel>();
826         reel->add(make_shared<dcp::ReelInteropSubtitleAsset>(c, dcp::Fraction(24, 1), 6046, 0));
827
828         string const issue_date = "2018-09-02T04:45:18+00:00";
829         string const issuer = "libdcp";
830         string const creator = "libdcp";
831         string const annotation_text = "Created by libdcp";
832
833         auto cpl = make_shared<dcp::CPL>("My film", dcp::ContentKind::FEATURE, dcp::Standard::INTEROP);
834         cpl->add (reel);
835         cpl->set_issuer (issuer);
836         cpl->set_creator (creator);
837         cpl->set_issue_date (issue_date);
838         cpl->set_annotation_text (annotation_text);
839         auto cv = cpl->content_version();
840         BOOST_REQUIRE (cv);
841         cv->label_text = "foo";
842         cpl->set_content_version (*cv);
843
844         dcp::DCP dcp ("build/test/write_interop_subtitle_test3");
845         dcp.add (cpl);
846         dcp.write_xml (issuer, creator, issue_date, annotation_text);
847
848         check_xml (
849                 dcp::file_to_string("test/ref/write_interop_subtitle_test3/subs.xml"),
850                 dcp::file_to_string("build/test/write_interop_subtitle_test3/subs.xml"),
851                 vector<string>()
852                 );
853         check_file ("build/test/write_interop_subtitle_test3/d36f4bb3-c4fa-4a95-9915-6fec3110cd71.png", "test/data/sub.png");
854
855         check_xml (
856                 dcp::file_to_string("test/ref/write_interop_subtitle_test3/ASSETMAP"),
857                 dcp::file_to_string("build/test/write_interop_subtitle_test3/ASSETMAP"),
858                 vector<string>()
859                 );
860
861         check_xml (
862                 dcp::file_to_string("test/ref/write_interop_subtitle_test3/pkl.xml"),
863                 dcp::file_to_string("build/test/write_interop_subtitle_test3/pkl_6a9e31a6-50a4-4ecb-8683-fa667848470a.xml"),
864                 vector<string>()
865                 );
866 }
867