X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=test%2Fwrite_subtitle_test.cc;h=074068f4c729e2a1d566f15a40cb6f09a66041ab;hb=d4f3f5b44d5d42eaadc6fa3807648b6735d61758;hp=648d5928272d19a441081d9220c7e30bb77ff8e4;hpb=a641fdc912a3f0749015decdf9e23ff15186ef78;p=libdcp.git diff --git a/test/write_subtitle_test.cc b/test/write_subtitle_test.cc index 648d5928..074068f4 100644 --- a/test/write_subtitle_test.cc +++ b/test/write_subtitle_test.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2015-2016 Carl Hetherington + Copyright (C) 2015-2019 Carl Hetherington This file is part of libdcp. @@ -15,19 +15,149 @@ You should have received a copy of the GNU General Public License along with libdcp. If not, see . + + In addition, as a special exception, the copyright holders give + permission to link the code of portions of this program with the + OpenSSL library under certain conditions as described in each + individual source file, and distribute linked combinations + including the two. + + You must obey the GNU General Public License in all respects + for all of the code used other than OpenSSL. If you modify + file(s) with this exception, you may extend this exception to your + version of the file(s), but you are not obligated to do so. If you + do not wish to do so, delete this exception statement from your + version. If you delete this exception statement from all source + files in the program, then also delete it here. */ #include "interop_subtitle_asset.h" #include "smpte_subtitle_asset.h" #include "subtitle_string.h" +#include "subtitle_image.h" +#include "subtitle_asset_internal.h" +#include "reel_subtitle_asset.h" +#include "reel.h" +#include "cpl.h" +#include "dcp.h" #include "test.h" +#include "util.h" #include using std::list; using std::string; using boost::shared_ptr; -/* Write some subtitle content as Interop XML and check that it is right */ +/** Test dcp::order::Font::take_intersection */ +BOOST_AUTO_TEST_CASE (take_intersection_test) +{ + dcp::order::Font A; + A._values["foo"] = "bar"; + A._values["fred"] = "jim"; + + dcp::order::Font B; + B._values["foo"] = "bar"; + B._values["sheila"] = "baz"; + + A.take_intersection (B); + BOOST_REQUIRE_EQUAL (A._values.size(), 1); + BOOST_CHECK_EQUAL (A._values["foo"], "bar"); + + A._values.clear (); + B._values.clear (); + + A._values["foo"] = "bar"; + A._values["fred"] = "jim"; + + B._values["foo"] = "hello"; + B._values["sheila"] = "baz"; + + A.take_intersection (B); + BOOST_CHECK_EQUAL (A._values.size(), 0); +} + +/** Test dcp::order::Font::take_difference */ +BOOST_AUTO_TEST_CASE (take_difference_test) +{ + dcp::order::Font A; + A._values["foo"] = "bar"; + A._values["fred"] = "jim"; + + dcp::order::Font B; + B._values["foo"] = "bar"; + B._values["sheila"] = "baz"; + + A.take_difference (B); + BOOST_REQUIRE_EQUAL (A._values.size(), 1); + BOOST_CHECK_EQUAL (A._values["fred"], "jim"); +} + +/** Test dcp::order::Subtitle::pull_fonts */ +BOOST_AUTO_TEST_CASE (pull_fonts_test1) +{ + shared_ptr root (new dcp::order::Part (shared_ptr ())); + shared_ptr sub1 (new dcp::order::Subtitle (root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time())); + root->children.push_back (sub1); + shared_ptr text1 (new dcp::order::Text (sub1, dcp::HALIGN_CENTER, 0, dcp::VALIGN_TOP, 0, dcp::DIRECTION_LTR)); + sub1->children.push_back (text1); + text1->font._values["font"] = "Inconsolata"; + text1->font._values["size"] = "42"; + + dcp::SubtitleAsset::pull_fonts (root); + + BOOST_REQUIRE_EQUAL (sub1->font._values.size(), 2); + BOOST_CHECK_EQUAL (sub1->font._values["font"], "Inconsolata"); + BOOST_CHECK_EQUAL (sub1->font._values["size"], "42"); + BOOST_CHECK_EQUAL (text1->font._values.size(), 0); +} + +/** Test dcp::order::Subtitle::pull_fonts */ +BOOST_AUTO_TEST_CASE (pull_fonts_test2) +{ + shared_ptr root (new dcp::order::Part (shared_ptr ())); + shared_ptr sub1 (new dcp::order::Subtitle (root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time())); + root->children.push_back (sub1); + shared_ptr text1 (new dcp::order::Text (sub1, dcp::HALIGN_CENTER, 0, dcp::VALIGN_TOP, 0, dcp::DIRECTION_LTR)); + sub1->children.push_back (text1); + text1->font._values["font"] = "Inconsolata"; + text1->font._values["size"] = "42"; + shared_ptr text2 (new dcp::order::Text (sub1, dcp::HALIGN_CENTER, 0, dcp::VALIGN_TOP, 0, dcp::DIRECTION_LTR)); + sub1->children.push_back (text2); + text2->font._values["font"] = "Inconsolata"; + text2->font._values["size"] = "48"; + + dcp::SubtitleAsset::pull_fonts (root); + + BOOST_REQUIRE_EQUAL (sub1->font._values.size(), 1); + BOOST_CHECK_EQUAL (sub1->font._values["font"], "Inconsolata"); + BOOST_REQUIRE_EQUAL (text1->font._values.size(), 1); + BOOST_CHECK_EQUAL (text1->font._values["size"], "42"); + BOOST_REQUIRE_EQUAL (text2->font._values.size(), 1); + BOOST_CHECK_EQUAL (text2->font._values["size"], "48"); +} + +/** Test dcp::order::Subtitle::pull_fonts */ +BOOST_AUTO_TEST_CASE (pull_fonts_test3) +{ + shared_ptr root (new dcp::order::Part (shared_ptr ())); + shared_ptr sub1 (new dcp::order::Subtitle (root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time())); + root->children.push_back (sub1); + shared_ptr text1 (new dcp::order::Text (sub1, dcp::HALIGN_CENTER, 0, dcp::VALIGN_TOP, 0, dcp::DIRECTION_LTR)); + sub1->children.push_back (text1); + dcp::order::Font font; + font._values["font"] = "Inconsolata"; + font._values["size"] = "42"; + shared_ptr string1 (new dcp::order::String (text1, font, "Hello world")); + text1->children.push_back (string1); + + dcp::SubtitleAsset::pull_fonts (root); + + BOOST_REQUIRE_EQUAL (sub1->font._values.size(), 2); + BOOST_CHECK_EQUAL (sub1->font._values["font"], "Inconsolata"); + BOOST_CHECK_EQUAL (sub1->font._values["size"], "42"); +} + +/** Write some subtitle content as Interop XML and check that it is right */ BOOST_AUTO_TEST_CASE (write_interop_subtitle_test) { dcp::InteropSubtitleAsset c; @@ -36,75 +166,235 @@ BOOST_AUTO_TEST_CASE (write_interop_subtitle_test) c.set_movie_title ("Test"); c.add ( - dcp::SubtitleString ( - string ("Frutiger"), - false, - false, - dcp::Colour (255, 255, 255), - 48, - 1.0, - dcp::Time (0, 4, 9, 22, 24), - dcp::Time (0, 4, 11, 22, 24), - 0, - dcp::HALIGN_CENTER, - 0.8, - dcp::VALIGN_TOP, - dcp::DIRECTION_LTR, - "Hello world", - dcp::NONE, - dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0, 24), - dcp::Time (0, 0, 0, 0, 24) + shared_ptr ( + new dcp::SubtitleString ( + string ("Frutiger"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 4, 9, 22, 24), + dcp::Time (0, 4, 11, 22, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "Hello world", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) ) ); c.add ( - dcp::SubtitleString ( - boost::optional (), - true, - true, - dcp::Colour (128, 0, 64), - 91, - 1.0, - dcp::Time (5, 41, 0, 21, 24), - dcp::Time (6, 12, 15, 21, 24), - 0, - dcp::HALIGN_CENTER, - 0.4, - dcp::VALIGN_BOTTOM, - dcp::DIRECTION_LTR, - "What's going on", - dcp::BORDER, - dcp::Colour (1, 2, 3), - dcp::Time (1, 2, 3, 4, 24), - dcp::Time (5, 6, 7, 8, 24) + shared_ptr ( + new dcp::SubtitleString ( + boost::optional (), + true, + true, + true, + dcp::Colour (128, 0, 64), + 91, + 1.0, + dcp::Time (5, 41, 0, 21, 24), + dcp::Time (6, 12, 15, 21, 24), + 0, + dcp::HALIGN_CENTER, + 0.4, + dcp::VALIGN_BOTTOM, + dcp::DIRECTION_LTR, + "What's going on", + dcp::BORDER, + dcp::Colour (1, 2, 3), + dcp::Time (1, 2, 3, 4, 24), + dcp::Time (5, 6, 7, 8, 24) + ) ) ); c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; check_xml ( + "" + "a6c58cff-3e1e-4b38-acec-a42224475ef6" + "Test" + "1" + "EN" + "" + "" + "Hello world" + "" + "" + "" + "" + "What's going on" + "" + "" + "", c.xml_as_string (), - "\n" - " a6c58cff-3e1e-4b38-acec-a42224475ef6\n" - " Test\n" - " 1\n" - " EN\n" - " \n" - " \n" - " Hello world\n" - " \n" - " \n" - " \n" - " \n" - " What's going on\n" - " \n" - " \n" + list () + ); +} + +/** Write some subtitle content as Interop XML and check that it is right. + * This test includes some horizontal alignment. + */ +BOOST_AUTO_TEST_CASE (write_interop_subtitle_test2) +{ + dcp::InteropSubtitleAsset c; + c.set_reel_number ("1"); + c.set_language ("EN"); + c.set_movie_title ("Test"); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Frutiger"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 4, 9, 22, 24), + dcp::Time (0, 4, 11, 22, 24), + -0.2, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "Hello world", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + boost::optional (), + true, + true, + true, + dcp::Colour (128, 0, 64), + 91, + 1.0, + dcp::Time (5, 41, 0, 21, 24), + dcp::Time (6, 12, 15, 21, 24), + -0.2, + dcp::HALIGN_CENTER, + 0.4, + dcp::VALIGN_BOTTOM, + dcp::DIRECTION_LTR, + "What's going on", + dcp::BORDER, + dcp::Colour (1, 2, 3), + dcp::Time (1, 2, 3, 4, 24), + dcp::Time (5, 6, 7, 8, 24) + ) + ) + ); + + c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; + + check_xml ( + "" + "a6c58cff-3e1e-4b38-acec-a42224475ef6" + "Test" + "1" + "EN" + "" + "" + "Hello world" + "" + "" + "" + "" + "What's going on" + "" + "" "", + c.xml_as_string (), list () ); } +/* Write some subtitle content as Interop XML using bitmaps and check that it is right */ +BOOST_AUTO_TEST_CASE (write_interop_subtitle_test3) +{ + RNGFixer fix; + + shared_ptr c (new dcp::InteropSubtitleAsset()); + c->set_reel_number ("1"); + c->set_language ("EN"); + c->set_movie_title ("Test"); + + c->add ( + shared_ptr ( + new dcp::SubtitleImage ( + dcp::Data ("test/data/sub.png"), + dcp::Time (0, 4, 9, 22, 24), + dcp::Time (0, 4, 11, 22, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c->_id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; + boost::filesystem::create_directories ("build/test/write_interop_subtitle_test3"); + c->write ("build/test/write_interop_subtitle_test3/subs.xml"); + + shared_ptr reel (new dcp::Reel()); + reel->add(shared_ptr(new dcp::ReelSubtitleAsset(c, dcp::Fraction(24, 1), 6046, 0))); + + dcp::XMLMetadata xml_meta; + xml_meta.issue_date = "2018-09-02T04:45:18+00:00"; + xml_meta.issuer = "libdcp"; + xml_meta.creator = "libdcp"; + xml_meta.annotation_text = "Created by libdcp"; + + shared_ptr cpl (new dcp::CPL ("My film", dcp::FEATURE)); + cpl->add (reel); + cpl->set_metadata (xml_meta); + cpl->set_content_version_label_text ("foo"); + + dcp::DCP dcp ("build/test/write_interop_subtitle_test3"); + dcp.add (cpl); + dcp.write_xml (dcp::INTEROP, xml_meta); + + check_xml ( + dcp::file_to_string("test/ref/write_interop_subtitle_test3/subs.xml"), + dcp::file_to_string("build/test/write_interop_subtitle_test3/subs.xml"), + list() + ); + check_file ("build/test/write_interop_subtitle_test3/ef5c6baa-be2d-4f86-9f15-b1acc792ee8b.png", "test/data/sub.png"); + + check_xml ( + dcp::file_to_string("test/ref/write_interop_subtitle_test3/ASSETMAP"), + dcp::file_to_string("build/test/write_interop_subtitle_test3/ASSETMAP"), + list() + ); + + check_xml ( + dcp::file_to_string("test/ref/write_interop_subtitle_test3/pkl.xml"), + dcp::file_to_string("build/test/write_interop_subtitle_test3/pkl_f5aab304-8145-44e3-a265-aa8d8812d8a2.xml"), + list() + ); +} + /* Write some subtitle content as SMPTE XML and check that it is right */ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test) { @@ -115,77 +405,316 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test) c.set_issue_date (dcp::LocalTime ("2016-04-01T03:52:00+00:00")); c.add ( - dcp::SubtitleString ( - string ("Frutiger"), - false, - false, - dcp::Colour (255, 255, 255), - 48, - 1.0, - dcp::Time (0, 4, 9, 22, 24), - dcp::Time (0, 4, 11, 22, 24), - 0, - dcp::HALIGN_CENTER, - 0.8, - dcp::VALIGN_TOP, - dcp::DIRECTION_LTR, - "Hello world", - dcp::NONE, - dcp::Colour (0, 0, 0), - dcp::Time (0, 0, 0, 0, 24), - dcp::Time (0, 0, 0, 0, 24) + shared_ptr ( + new dcp::SubtitleString ( + string ("Frutiger"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 4, 9, 22, 24), + dcp::Time (0, 4, 11, 22, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "Hello world", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) ) ); c.add ( - dcp::SubtitleString ( - boost::optional (), - true, - true, - dcp::Colour (128, 0, 64), - 91, - 1.0, - dcp::Time (5, 41, 0, 21, 24), - dcp::Time (6, 12, 15, 21, 24), - 0, - dcp::HALIGN_CENTER, - 0.4, - dcp::VALIGN_BOTTOM, - dcp::DIRECTION_RTL, - "What's going on", - dcp::BORDER, - dcp::Colour (1, 2, 3), - dcp::Time (1, 2, 3, 4, 24), - dcp::Time (5, 6, 7, 8, 24) + shared_ptr ( + new dcp::SubtitleString ( + boost::optional (), + true, + true, + true, + dcp::Colour (128, 0, 64), + 91, + 1.0, + dcp::Time (5, 41, 0, 21, 24), + dcp::Time (6, 12, 15, 21, 24), + 0, + dcp::HALIGN_CENTER, + 0.4, + dcp::VALIGN_BOTTOM, + dcp::DIRECTION_RTL, + "What's going on", + dcp::BORDER, + dcp::Colour (1, 2, 3), + dcp::Time (1, 2, 3, 4, 24), + dcp::Time (5, 6, 7, 8, 24) + ) ) ); - c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; + c._xml_id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; check_xml ( + "" + "" + "urn:uuid:a6c58cff-3e1e-4b38-acec-a42224475ef6" + "Test" + "2016-04-01T03:52:00.000+00:00" + "1" + "EN" + "24 1" + "24" + "" + "" + "" + "Hello world" + "" + "" + "" + "" + "What's going on" + "" + "" + "" + "", c.xml_as_string (), - "\n" - "\n" - " urn:uuid:a6c58cff-3e1e-4b38-acec-a42224475ef6\n" - " Test\n" - " 2016-04-01T03:52:00.000+00:00\n" - " 1\n" - " EN\n" - " 24 1\n" - " 24\n" - " \n" - " \n" - " \n" - " Hello world\n" - " \n" - " \n" - " \n" - " \n" - " What's going on\n" - " \n" - " \n" - " \n" - "\n", list () ); } + +/* Write some subtitle content as SMPTE XML and check that it is right. + This includes in-line font changes. +*/ +BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test2) +{ + dcp::SMPTESubtitleAsset c; + c.set_reel_number (1); + c.set_language ("EN"); + c.set_content_title_text ("Test"); + c.set_issue_date (dcp::LocalTime ("2016-04-01T03:52:00+00:00")); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "Testing is ", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + true, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "really", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + " fun", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.9, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "This is the ", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + true, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.9, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + "second", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c.add ( + shared_ptr ( + new dcp::SubtitleString ( + string ("Arial"), + false, + false, + false, + dcp::Colour (255, 255, 255), + 48, + 1.0, + dcp::Time (0, 0, 1, 0, 24), + dcp::Time (0, 0, 9, 0, 24), + 0, + dcp::HALIGN_CENTER, + 0.9, + dcp::VALIGN_TOP, + dcp::DIRECTION_LTR, + " line", + dcp::NONE, + dcp::Colour (0, 0, 0), + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c._xml_id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; + + check_xml ( + c.xml_as_string (), + "" + "" + "urn:uuid:a6c58cff-3e1e-4b38-acec-a42224475ef6" + "Test" + "2016-04-01T03:52:00.000+00:00" + "1" + "EN" + "24 1" + "24" + "" + "" + "" + "" + "Testing is " + "really" + " fun" + "" + "" + "This is the " + "second" + " line" + "" + "" + "" + "" + "", + list () + ); +} + +/* Write some subtitle content as SMPTE using bitmaps and check that it is right */ +BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test3) +{ + dcp::SMPTESubtitleAsset c; + c.set_reel_number (1); + c.set_language ("EN"); + c.set_content_title_text ("Test"); + + c.add ( + shared_ptr ( + new dcp::SubtitleImage ( + dcp::Data ("test/data/sub.png"), + dcp::Time (0, 4, 9, 22, 24), + dcp::Time (0, 4, 11, 22, 24), + 0, + dcp::HALIGN_CENTER, + 0.8, + dcp::VALIGN_TOP, + dcp::Time (0, 0, 0, 0, 24), + dcp::Time (0, 0, 0, 0, 24) + ) + ) + ); + + c._id = "a6c58cff-3e1e-4b38-acec-a42224475ef6"; + + boost::filesystem::create_directories ("build/test/write_smpte_subtitle_test3"); + c.write ("build/test/write_smpte_subtitle_test3/subs.mxf"); + + /* XXX: check this result when we can read them back in again */ +}