X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Finterop_subtitle_asset.cc;h=ac3dcc98e943e7aa077e99b0c7a6963117be9ebd;hb=f11ff8d4d961d92e994ef0f9beb456aa8ec7c4cb;hp=cfd37cb8c85b92171d51a6e0b96c13c9eab81dee;hpb=a1d530be29598018b32b0b709fd8c769e972bd15;p=libdcp.git diff --git a/src/interop_subtitle_asset.cc b/src/interop_subtitle_asset.cc index cfd37cb8..ac3dcc98 100644 --- a/src/interop_subtitle_asset.cc +++ b/src/interop_subtitle_asset.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington + Copyright (C) 2012-2018 Carl Hetherington This file is part of libdcp. @@ -33,13 +33,17 @@ #include "interop_subtitle_asset.h" #include "interop_load_font_node.h" +#include "subtitle_asset_internal.h" #include "xml.h" #include "raw_convert.h" #include "util.h" #include "font_asset.h" #include "dcp_assert.h" +#include "compose.hpp" +#include "subtitle_image.h" #include #include +#include #include #include @@ -48,22 +52,24 @@ using std::string; using std::cout; using std::cerr; using std::map; -using boost::shared_ptr; +using std::shared_ptr; using boost::shared_array; using boost::optional; -using boost::dynamic_pointer_cast; +using std::dynamic_pointer_cast; using namespace dcp; InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file) : SubtitleAsset (file) { + _raw_xml = dcp::file_to_string (file); + shared_ptr xml (new cxml::Document ("DCSubtitle")); xml->read_file (file); _id = xml->string_child ("SubtitleID"); _reel_number = xml->string_child ("ReelNumber"); _language = xml->string_child ("Language"); _movie_title = xml->string_child ("MovieTitle"); - _load_font_nodes = type_children (xml, "LoadFont"); + _load_font_nodes = type_children (xml, "LoadFont"); /* Now we need to drop down to xmlpp */ @@ -75,6 +81,13 @@ InteropSubtitleAsset::InteropSubtitleAsset (boost::filesystem::path file) parse_subtitles (e, ps, optional(), INTEROP); } } + + BOOST_FOREACH (shared_ptr i, _subtitles) { + shared_ptr si = dynamic_pointer_cast(i); + if (si) { + si->read_png_file (file.parent_path() / String::compose("%1.png", si->id())); + } + } } InteropSubtitleAsset::InteropSubtitleAsset () @@ -106,10 +119,11 @@ InteropSubtitleAsset::xml_as_string () const } void -InteropSubtitleAsset::add_font (string load_id, boost::filesystem::path file) +InteropSubtitleAsset::add_font (string load_id, dcp::ArrayData data) { - _fonts.push_back (Font (load_id, make_uuid(), file)); - _load_font_nodes.push_back (shared_ptr (new InteropLoadFontNode (load_id, file.leaf().string ()))); + _fonts.push_back (Font(load_id, make_uuid(), data)); + string const uri = String::compose("font_%1.ttf", _load_font_nodes.size()); + _load_font_nodes.push_back (shared_ptr(new InteropLoadFontNode(load_id, uri))); } bool @@ -124,22 +138,24 @@ InteropSubtitleAsset::equals (shared_ptr other_asset, EqualityOptio return false; } - list >::const_iterator i = _load_font_nodes.begin (); - list >::const_iterator j = other->_load_font_nodes.begin (); + if (!options.load_font_nodes_can_differ) { + list >::const_iterator i = _load_font_nodes.begin (); + list >::const_iterator j = other->_load_font_nodes.begin (); - while (i != _load_font_nodes.end ()) { - if (j == other->_load_font_nodes.end ()) { - note (DCP_ERROR, " nodes differ"); - return false; - } + while (i != _load_font_nodes.end ()) { + if (j == other->_load_font_nodes.end ()) { + note (DCP_ERROR, " nodes differ"); + return false; + } - if (**i != **j) { - note (DCP_ERROR, " nodes differ"); - return false; - } + if (**i != **j) { + note (DCP_ERROR, " nodes differ"); + return false; + } - ++i; - ++j; + ++i; + ++j; + } } if (_movie_title != other->_movie_title) { @@ -174,24 +190,32 @@ InteropSubtitleAsset::write (boost::filesystem::path p) const _file = p; + /* Image subtitles */ + BOOST_FOREACH (shared_ptr i, _subtitles) { + shared_ptr im = dynamic_pointer_cast (i); + if (im) { + im->write_png_file(p.parent_path() / String::compose("%1.png", im->id())); + } + } + + /* Fonts */ BOOST_FOREACH (shared_ptr i, _load_font_nodes) { boost::filesystem::path file = p.parent_path() / i->uri; - FILE* f = fopen_boost (file, "wb"); - if (!f) { - throw FileError ("could not open font file for writing", file, errno); - } list::const_iterator j = _fonts.begin (); while (j != _fonts.end() && j->load_id != i->id) { ++j; } if (j != _fonts.end ()) { - fwrite (j->data.data().get(), 1, j->data.size(), f); + j->data.write (file); j->file = file; } - fclose (f); } } +/** Look at a supplied list of assets and find the fonts. Then match these + * fonts up with anything requested by a so that _fonts contains + * a list of font ID, load ID and data. + */ void InteropSubtitleAsset::resolve_fonts (list > assets) { @@ -202,7 +226,15 @@ InteropSubtitleAsset::resolve_fonts (list > assets) } BOOST_FOREACH (shared_ptr j, _load_font_nodes) { - if (font->file() && j->uri == font->file()->leaf().string ()) { + bool got = false; + BOOST_FOREACH (Font const & k, _fonts) { + if (k.load_id == j->id) { + got = true; + break; + } + } + + if (!got && font->file() && j->uri == font->file()->leaf().string()) { _fonts.push_back (Font (j->id, i->id(), font->file().get())); } } @@ -217,3 +249,49 @@ InteropSubtitleAsset::add_font_assets (list >& assets) assets.push_back (shared_ptr (new FontAsset (i.uuid, i.file.get ()))); } } + +void +InteropSubtitleAsset::write_to_assetmap (xmlpp::Node* node, boost::filesystem::path root) const +{ + Asset::write_to_assetmap (node, root); + + BOOST_FOREACH (shared_ptr i, _subtitles) { + shared_ptr im = dynamic_pointer_cast (i); + if (im) { + DCP_ASSERT (im->file()); + write_file_to_assetmap (node, root, im->file().get(), im->id()); + } + } +} + +void +InteropSubtitleAsset::add_to_pkl (shared_ptr pkl, boost::filesystem::path root) const +{ + Asset::add_to_pkl (pkl, root); + + BOOST_FOREACH (shared_ptr i, _subtitles) { + shared_ptr im = dynamic_pointer_cast (i); + if (im) { + ArrayData png_image = im->png_image (); + pkl->add_asset (im->id(), optional(), make_digest(png_image), png_image.size(), "image/png"); + } + } +} + + +void +InteropSubtitleAsset::set_font_file (string load_id, boost::filesystem::path file) +{ + BOOST_FOREACH (Font& i, _fonts) { + if (i.load_id == load_id) { + i.file = file; + } + } + + BOOST_FOREACH (shared_ptr i, _load_font_nodes) { + if (i->id == load_id) { + i->uri = file.filename().string(); + } + } +} +