#include <fstream>
#include <boost/filesystem.hpp>
#include <boost/function.hpp>
+#include <boost/lexical_cast.hpp>
#include "AS_DCP.h"
#include "KM_util.h"
#include "asset.h"
}
void
-Asset::write_to_pkl (ostream& s) const
+Asset::write_to_pkl (xmlpp::Node* node) const
{
- s << " <Asset>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <Hash>" << digest() << "</Hash>\n"
- << " <Size>" << filesystem::file_size(path()) << "</Size>\n"
- << " <Type>application/mxf</Type>\n"
- << " </Asset>\n";
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ asset->add_child("AnnotationText")->add_child_text (_file_name);
+ asset->add_child("Hash")->add_child_text (digest ());
+ asset->add_child("Size")->add_child_text (lexical_cast<string> (filesystem::file_size(path())));
+ asset->add_child("Type")->add_child_text ("application/mxf");
}
void
-Asset::write_to_assetmap (ostream& s) const
+Asset::write_to_assetmap (xmlpp::Node* node) const
{
- s << " <Asset>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <ChunkList>\n"
- << " <Chunk>\n"
- << " <Path>" << _file_name << "</Path>\n"
- << " <VolumeIndex>1</VolumeIndex>\n"
- << " <Offset>0</Offset>\n"
- << " <Length>" << filesystem::file_size(path()) << "</Length>\n"
- << " </Chunk>\n"
- << " </ChunkList>\n"
- << " </Asset>\n";
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
+ xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
+ chunk->add_child("Path")->add_child_text (_file_name);
+ chunk->add_child("VolumeIndex")->add_child_text ("1");
+ chunk->add_child("Offset")->add_child_text ("0");
+ chunk->add_child("Length")->add_child_text (lexical_cast<string> (filesystem::file_size(path())));
}
filesystem::path
#include <list>
#include <boost/filesystem.hpp>
#include <boost/function.hpp>
+#include <libxml++/libxml++.h>
#include "types.h"
namespace ASDCP {
/** Write details of the asset to a CPL stream.
* @param s Stream.
*/
- virtual void write_to_cpl (std::ostream& s) const = 0;
+ virtual void write_to_cpl (xmlpp::Node *) const = 0;
/** Write details of the asset to a PKL stream.
* @param s Stream.
*/
- void write_to_pkl (std::ostream& s) const;
+ void write_to_pkl (xmlpp::Node *) const;
/** Write details of the asset to a ASSETMAP stream.
* @param s Stream.
*/
- void write_to_assetmap (std::ostream& s) const;
+ void write_to_assetmap (xmlpp::Node *) const;
std::string uuid () const {
return _uuid;
using std::ostream;
using std::list;
using boost::shared_ptr;
+using boost::lexical_cast;
using namespace libdcp;
CPL::CPL (string directory, string name, ContentKind content_kind, int length, int frames_per_second)
stringstream s;
s << _uuid << "_cpl.xml";
p /= s.str();
- ofstream os (p.string().c_str());
-
- os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<CompositionPlaylist xmlns=\"http://www.smpte-ra.org/schemas/429-7/2006/CPL\">\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _name << "</AnnotationText>\n"
- << " <IssueDate>" << metadata.issue_date << "</IssueDate>\n"
- << " <Creator>" << metadata.creator << "</Creator>\n"
- << " <ContentTitleText>" << _name << "</ContentTitleText>\n"
- << " <ContentKind>" << content_kind_to_string (_content_kind) << "</ContentKind>\n"
- << " <ContentVersion>\n"
- << " <Id>urn:uri:" << _uuid << "_" << metadata.issue_date << "</Id>\n"
- << " <LabelText>" << _uuid << "_" << metadata.issue_date << "</LabelText>\n"
- << " </ContentVersion>\n"
- << " <RatingList/>\n"
- << " <ReelList>\n";
+
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("CompositionPlaylist", "http://www.smpte-ra.org/schemas/429-7/2006/CPL");
+ root->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ root->add_child("AnnotationText")->add_child_text (_name);
+ root->add_child("IssueDate")->add_child_text (metadata.issue_date);
+ root->add_child("Creator")->add_child_text (metadata.creator);
+ root->add_child("ContentTitleText")->add_child_text (_name);
+ root->add_child("ContentKind")->add_child_text (content_kind_to_string (_content_kind));
+ {
+ xmlpp::Node* cv = root->add_child ("ContentVersion");
+ cv->add_child ("Id")->add_child_text ("urn:uri:" + _uuid + "_" + metadata.issue_date);
+ cv->add_child ("LabelText")->add_child_text (_uuid + "_" + metadata.issue_date);
+ }
+ root->add_child("RatingList");
+
+ xmlpp::Node* reel_list = root->add_child ("ReelList");
for (list<shared_ptr<const Reel> >::const_iterator i = _reels.begin(); i != _reels.end(); ++i) {
- (*i)->write_to_cpl (os);
+ (*i)->write_to_cpl (reel_list);
}
- os << " </ReelList>\n"
- << "</CompositionPlaylist>\n";
-
- os.close ();
+ doc.write_to_file_formatted (p.string (), "UTF-8");
_digest = make_digest (p.string ());
_length = boost::filesystem::file_size (p.string ());
}
void
-CPL::write_to_pkl (ostream& s) const
+CPL::write_to_pkl (xmlpp::Node* node) const
{
- s << " <Asset>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <Hash>" << _digest << "</Hash>\n"
- << " <Size>" << _length << "</Size>\n"
- << " <Type>text/xml</Type>\n"
- << " </Asset>\n";
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ asset->add_child("Hash")->add_child_text (_digest);
+ asset->add_child("Size")->add_child_text (lexical_cast<string> (_length));
+ asset->add_child("Type")->add_child_text ("text/xml");
}
list<shared_ptr<const Asset> >
}
void
-CPL::write_to_assetmap (ostream& s) const
+CPL::write_to_assetmap (xmlpp::Node* node) const
{
- s << " <Asset>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <ChunkList>\n"
- << " <Chunk>\n"
- << " <Path>" << _uuid << "_cpl.xml</Path>\n"
- << " <VolumeIndex>1</VolumeIndex>\n"
- << " <Offset>0</Offset>\n"
- << " <Length>" << _length << "</Length>\n"
- << " </Chunk>\n"
- << " </ChunkList>\n"
- << " </Asset>\n";
+ xmlpp::Node* asset = node->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + _uuid);
+ xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
+ xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
+ chunk->add_child("Path")->add_child_text (_uuid + "_cpl.xml");
+ chunk->add_child("VolumeIndex")->add_child_text ("1");
+ chunk->add_child("Offset")->add_child_text("0");
+ chunk->add_child("Length")->add_child_text(lexical_cast<string> (_length));
}
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
+#include <libxml++/libxml++.h>
#include "types.h"
namespace libdcp {
bool equals (CPL const & other, EqualityOptions options, boost::function<void (NoteType, std::string)> note) const;
void write_xml (XMLMetadata const &) const;
- void write_to_assetmap (std::ostream& s) const;
- void write_to_pkl (std::ostream& s) const;
+ void write_to_assetmap (xmlpp::Node *) const;
+ void write_to_pkl (xmlpp::Node *) const;
private:
std::string _directory;
#include <iostream>
#include <boost/filesystem.hpp>
#include <boost/algorithm/string.hpp>
+#include <boost/lexical_cast.hpp>
#include <libxml++/libxml++.h>
#include "dcp.h"
#include "asset.h"
using std::ofstream;
using std::ostream;
using boost::shared_ptr;
+using boost::lexical_cast;
using namespace libdcp;
DCP::DCP (string directory)
stringstream s;
s << pkl_uuid << "_pkl.xml";
p /= s.str();
- ofstream pkl (p.string().c_str());
-
- pkl << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<PackingList xmlns=\"http://www.smpte-ra.org/schemas/429-8/2007/PKL\">\n"
- << " <Id>urn:uuid:" << pkl_uuid << "</Id>\n"
- /* XXX: this is a bit of a hack */
- << " <AnnotationText>" << _cpls.front()->name() << "</AnnotationText>\n"
- << " <IssueDate>" << metadata.issue_date << "</IssueDate>\n"
- << " <Issuer>" << metadata.issuer << "</Issuer>\n"
- << " <Creator>" << metadata.creator << "</Creator>\n"
- << " <AssetList>\n";
+
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("PackingList", "http://www.smpte-ra.org/schemas/429-8/2007/PKL");
+
+ root->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid);
+ /* XXX: this is a bit of a hack */
+ root->add_child("AnnotationText")->add_child_text (_cpls.front()->name());
+ root->add_child("IssueDate")->add_child_text (metadata.issue_date);
+ root->add_child("Issuer")->add_child_text (metadata.issuer);
+ root->add_child("Creator")->add_child_text (metadata.creator);
+
+ xmlpp::Node* asset_list = root->add_child ("AssetList");
list<shared_ptr<const Asset> > a = assets ();
for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) {
- (*i)->write_to_pkl (pkl);
+ (*i)->write_to_pkl (asset_list);
}
for (list<shared_ptr<const CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
- (*i)->write_to_pkl (pkl);
+ (*i)->write_to_pkl (asset_list);
}
- pkl << " </AssetList>\n"
- << "</PackingList>\n";
-
+ doc.write_to_file_formatted (p.string (), "UTF-8");
return p.string ();
}
boost::filesystem::path p;
p /= _directory;
p /= "VOLINDEX.xml";
- ofstream vi (p.string().c_str());
- vi << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<VolumeIndex xmlns=\"http://www.smpte-ra.org/schemas/429-9/2007/AM\">\n"
- << " <Index>1</Index>\n"
- << "</VolumeIndex>\n";
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("VolumeIndex", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
+ root->add_child("Index")->add_child_text ("1");
+ doc.write_to_file_formatted (p.string (), "UTF-8");
}
void
boost::filesystem::path p;
p /= _directory;
p /= "ASSETMAP.xml";
- ofstream am (p.string().c_str());
-
- am << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<AssetMap xmlns=\"http://www.smpte-ra.org/schemas/429-9/2007/AM\">\n"
- << " <Id>urn:uuid:" << make_uuid() << "</Id>\n"
- << " <Creator>" << metadata.creator << "</Creator>\n"
- << " <VolumeCount>1</VolumeCount>\n"
- << " <IssueDate>" << metadata.issue_date << "</IssueDate>\n"
- << " <Issuer>" << metadata.issuer << "</Issuer>\n"
- << " <AssetList>\n";
-
- am << " <Asset>\n"
- << " <Id>urn:uuid:" << pkl_uuid << "</Id>\n"
- << " <PackingList>true</PackingList>\n"
- << " <ChunkList>\n"
- << " <Chunk>\n"
- << " <Path>" << pkl_uuid << "_pkl.xml</Path>\n"
- << " <VolumeIndex>1</VolumeIndex>\n"
- << " <Offset>0</Offset>\n"
- << " <Length>" << pkl_length << "</Length>\n"
- << " </Chunk>\n"
- << " </ChunkList>\n"
- << " </Asset>\n";
+
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("AssetMap", "http://www.smpte-ra.org/schemas/429-9/2007/AM");
+
+ root->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid());
+ root->add_child("Creator")->add_child_text (metadata.creator);
+ root->add_child("VolumeCount")->add_child_text ("1");
+ root->add_child("IssueDate")->add_child_text (metadata.issue_date);
+ root->add_child("Issuer")->add_child_text (metadata.issuer);
+ xmlpp::Node* asset_list = root->add_child ("AssetList");
+
+ xmlpp::Node* asset = asset_list->add_child ("Asset");
+ asset->add_child("Id")->add_child_text ("urn:uuid:" + pkl_uuid);
+ asset->add_child("PackingList")->add_child_text ("true");
+ xmlpp::Node* chunk_list = asset->add_child ("ChunkList");
+ xmlpp::Node* chunk = chunk_list->add_child ("Chunk");
+ chunk->add_child("Path")->add_child_text (pkl_uuid + "_pkl.xml");
+ chunk->add_child("VolumeIndex")->add_child_text ("1");
+ chunk->add_child("Offset")->add_child_text ("0");
+ chunk->add_child("Length")->add_child_text (lexical_cast<string> (pkl_length));
for (list<shared_ptr<const CPL> >::const_iterator i = _cpls.begin(); i != _cpls.end(); ++i) {
- (*i)->write_to_assetmap (am);
+ (*i)->write_to_assetmap (asset_list);
}
list<shared_ptr<const Asset> > a = assets ();
for (list<shared_ptr<const Asset> >::const_iterator i = a.begin(); i != a.end(); ++i) {
- (*i)->write_to_assetmap (am);
+ (*i)->write_to_assetmap (asset_list);
}
- am << " </AssetList>\n"
- << "</AssetMap>\n";
+ doc.write_to_file_formatted (p.string (), "UTF-8");
}
}
void
-PictureAsset::write_to_cpl (ostream& s) const
+PictureAsset::write_to_cpl (xmlpp::Node* node) const
{
- s << " <MainPicture>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EditRate>" << _edit_rate << " 1</EditRate>\n"
- << " <IntrinsicDuration>" << _intrinsic_duration << "</IntrinsicDuration>\n"
- << " <EntryPoint>" << _entry_point << "</EntryPoint>\n"
- << " <Duration>" << _duration << "</Duration>\n"
- << " <FrameRate>" << _edit_rate << " 1</FrameRate>\n"
- << " <ScreenAspectRatio>" << _size.width << " " << _size.height << "</ScreenAspectRatio>\n"
- << " </MainPicture>\n";
+ xmlpp::Node* mp = node->add_child ("MainPicture");
+ mp->add_child ("Id")->add_child_text ("urn:uuid:" + _uuid);
+ mp->add_child ("AnnotationText")->add_child_text (_file_name);
+ mp->add_child ("EditRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1");
+ mp->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration));
+ mp->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point));
+ mp->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration));
+ mp->add_child ("FrameRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1");
+ mp->add_child ("ScreenAspectRatio")->add_child_text (lexical_cast<string> (_size.width) + " " + lexical_cast<string> (_size.height));
}
bool
*/
PictureAsset (std::string directory, std::string mxf_name, boost::signals2::signal<void (float)>* progress, int fps, int intrinsic_duration, Size size);
- /** Write details of this asset to a CPL stream.
- * @param s Stream.
+ /** Write details of this asset to a CPL XML node.
+ * @param node Node.
*/
- void write_to_cpl (std::ostream& s) const;
+ void write_to_cpl (xmlpp::Node* node) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
using namespace libdcp;
void
-Reel::write_to_cpl (ostream& s) const
+Reel::write_to_cpl (xmlpp::Node* node) const
{
- s << " <Reel>\n"
- << " <Id>urn:uuid:" << make_uuid() << "</Id>\n"
- << " <AssetList>\n";
+ xmlpp::Node* reel = node->add_child ("Reel");
+ reel->add_child("Id")->add_child_text ("urn:uuid:" + make_uuid());
+ xmlpp::Node* asset_list = reel->add_child ("AssetList");
if (_main_picture) {
- _main_picture->write_to_cpl (s);
+ _main_picture->write_to_cpl (asset_list);
}
if (_main_sound) {
- _main_sound->write_to_cpl (s);
+ _main_sound->write_to_cpl (asset_list);
}
if (_main_subtitle) {
- _main_subtitle->write_to_cpl (s);
+ _main_subtitle->write_to_cpl (asset_list);
}
-
- s << " </AssetList>\n"
- << " </Reel>\n";
}
bool
#include <list>
#include <boost/shared_ptr.hpp>
#include <boost/function.hpp>
+#include <libxml++/libxml++.h>
#include "types.h"
namespace libdcp {
return _main_subtitle;
}
- void write_to_cpl (std::ostream & s) const;
+ void write_to_cpl (xmlpp::Node *) const;
bool equals (boost::shared_ptr<const Reel> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> notes) const;
}
void
-SoundAsset::write_to_cpl (ostream& s) const
+SoundAsset::write_to_cpl (xmlpp::Node* node) const
{
- s << " <MainSound>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EditRate>" << _edit_rate << " 1</EditRate>\n"
- << " <IntrinsicDuration>" << _intrinsic_duration << "</IntrinsicDuration>\n"
- << " <EntryPoint>" << _entry_point << "</EntryPoint>\n"
- << " <Duration>" << _duration << "</Duration>\n"
- << " </MainSound>\n";
+ xmlpp::Node* ms = node->add_child ("MainSound");
+ ms->add_child ("Id")->add_child_text ("urn:uuid:" + _uuid);
+ ms->add_child ("AnnotationText")->add_child_text (_file_name);
+ ms->add_child ("EditRate")->add_child_text (lexical_cast<string> (_edit_rate) + " 1");
+ ms->add_child ("IntrinsicDuration")->add_child_text (lexical_cast<string> (_intrinsic_duration));
+ ms->add_child ("EntryPoint")->add_child_text (lexical_cast<string> (_entry_point));
+ ms->add_child ("Duration")->add_child_text (lexical_cast<string> (_duration));
}
bool
boost::shared_ptr<SoundAssetWriter> start_write (MXFMetadata const & metadata = MXFMetadata ());
- /** Write details of this asset to a CPL stream.
- * @param s Stream.
+ /** Write details of this asset to a CPL XML node.
+ * @param node Node.
*/
- void write_to_cpl (std::ostream& s) const;
+ void write_to_cpl (xmlpp::Node* node) const;
bool equals (boost::shared_ptr<const Asset> other, EqualityOptions opt, boost::function<void (NoteType, std::string)> note) const;
}
void
-SubtitleAsset::write_to_cpl (ostream& s) const
+SubtitleAsset::write_to_cpl (xmlpp::Node* node) const
{
/* XXX: should EditRate, Duration and IntrinsicDuration be in here? */
-
- s << " <MainSubtitle>\n"
- << " <Id>urn:uuid:" << _uuid << "</Id>\n"
- << " <AnnotationText>" << _file_name << "</AnnotationText>\n"
- << " <EntryPoint>0</EntryPoint>\n"
- << " </MainSubtitle>\n";
+
+ xmlpp::Node* ms = node->add_child ("MainSubtitle");
+ ms->add_child("Id")->add_child_text("urn:uuid:" + _uuid);
+ ms->add_child("AnnotationText")->add_child_text (_file_name);
+ /* XXX */
+ ms->add_child("EntryPoint")->add_child_text ("0");
}
struct SubtitleSorter {
void
SubtitleAsset::write_xml () const
{
- ofstream f (path().string().c_str());
- write_xml (f);
+ ofstream s (path().string().c_str());
+ write_xml (s);
}
void
SubtitleAsset::write_xml (ostream& s) const
{
- s << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
- << "<DCSubtitle Version=\"1.0\">\n"
- << " <SubtitleID>" << _uuid << "</SubtitleID>\n"
- << " <MovieTitle>" << _movie_title << "</MovieTitle>\n"
- << " <ReelNumber>" << _reel_number << "</ReelNumber>\n"
- << " <Language>" << _language << "</Language>\n";
+ xmlpp::Document doc;
+ xmlpp::Element* root = doc.create_root_node ("DCSubtitle");
+ root->set_attribute ("Version", "1.0");
+
+ root->add_child("SubtitleID")->add_child_text (_uuid);
+ root->add_child("MovieTitle")->add_child_text (_movie_title);
+ root->add_child("ReelNumber")->add_child_text (lexical_cast<string> (_reel_number));
+ root->add_child("Language")->add_child_text (_language);
if (_load_font_nodes.size() > 1) {
boost::throw_exception (MiscError ("multiple LoadFont nodes not supported"));
}
if (!_load_font_nodes.empty ()) {
- s << " <LoadFont Id=\"" << _load_font_nodes.front()->id << "\" URI=\"" << _load_font_nodes.front()->uri << "\"/>\n";
+ xmlpp::Element* load_font = root->add_child("LoadFont");
+ load_font->set_attribute("Id", _load_font_nodes.front()->id);
+ load_font->set_attribute("URI", _load_font_nodes.front()->uri);
}
list<shared_ptr<Subtitle> > sorted = _subtitles;
/* XXX: multiple fonts not supported */
/* XXX: script, underlined, weight not supported */
- bool first = true;
bool italic = false;
Color color;
int size = 0;
Time last_fade_up_time;
Time last_fade_down_time;
+ xmlpp::Element* font = 0;
+ xmlpp::Element* subtitle = 0;
+
for (list<shared_ptr<Subtitle> >::iterator i = sorted.begin(); i != sorted.end(); ++i) {
/* We will start a new <Font>...</Font> whenever some font property changes.
- I suppose should really make an optimal hierarchy of <Font> tags, but
+ I suppose we should really make an optimal hierarchy of <Font> tags, but
that seems hard.
*/
- bool const font_changed = first ||
+ bool const font_changed =
italic != (*i)->italic() ||
color != (*i)->color() ||
size != (*i)->size() ||
effect != (*i)->effect() ||
effect_color != (*i)->effect_color();
- stringstream a;
if (font_changed) {
italic = (*i)->italic ();
- a << "Italic=\"" << (italic ? "yes" : "no") << "\" ";
color = (*i)->color ();
- a << "Color=\"" << color.to_argb_string() << "\" ";
size = (*i)->size ();
- a << "Size=\"" << size << "\" ";
effect = (*i)->effect ();
- a << "Effect=\"" << effect_to_string(effect) << "\" ";
effect_color = (*i)->effect_color ();
- a << "EffectColor=\"" << effect_color.to_argb_string() << "\" ";
- a << "Script=\"normal\" Underlined=\"no\" Weight=\"normal\"";
}
- if (first || font_changed ||
+ if (!font || font_changed) {
+ font = root->add_child ("Font");
+ string id = "theFontId";
+ if (!_load_font_nodes.empty()) {
+ id = _load_font_nodes.front()->id;
+ }
+ font->set_attribute ("Id", id);
+ font->set_attribute ("Italic", italic ? "yes" : "no");
+ font->set_attribute ("Color", color.to_argb_string());
+ font->set_attribute ("Size", lexical_cast<string> (size));
+ font->set_attribute ("Effect", effect_to_string (effect));
+ font->set_attribute ("EffectColor", effect_color.to_argb_string());
+ font->set_attribute ("Script", "normal");
+ font->set_attribute ("Underlined", "no");
+ font->set_attribute ("Weight", "normal");
+ }
+
+ if (!subtitle ||
(last_in != (*i)->in() ||
last_out != (*i)->out() ||
last_fade_up_time != (*i)->fade_up_time() ||
last_fade_down_time != (*i)->fade_down_time()
)) {
- if (!first) {
- s << " </Subtitle>\n";
- }
-
- if (font_changed) {
- if (!first) {
- s << " </Font>\n";
- }
-
- string id = "theFontId";
- if (!_load_font_nodes.empty()) {
- id = _load_font_nodes.front()->id;
- }
-
- s << " <Font Id=\"" << id << "\" " << a.str() << ">\n";
- }
-
- s << " <Subtitle "
- << "SpotNumber=\"" << spot_number++ << "\" "
- << "TimeIn=\"" << (*i)->in().to_string() << "\" "
- << "TimeOut=\"" << (*i)->out().to_string() << "\" "
- << "FadeUpTime=\"" << (*i)->fade_up_time().to_ticks() << "\" "
- << "FadeDownTime=\"" << (*i)->fade_down_time().to_ticks() << "\""
- << ">\n";
+ subtitle = font->add_child ("Subtitle");
+ subtitle->set_attribute ("SpotNumber", lexical_cast<string> (spot_number++));
+ subtitle->set_attribute ("TimeIn", (*i)->in().to_string());
+ subtitle->set_attribute ("TimeOut", (*i)->out().to_string());
+ subtitle->set_attribute ("FadeUpTime", lexical_cast<string> ((*i)->fade_up_time().to_ticks()));
+ subtitle->set_attribute ("FadeDownTime", lexical_cast<string> ((*i)->fade_down_time().to_ticks()));
last_in = (*i)->in ();
last_out = (*i)->out ();
last_fade_down_time = (*i)->fade_down_time ();
}
- s << " <Text "
- << "VAlign=\"" << valign_to_string ((*i)->v_align()) << "\" "
- << "VPosition=\"" << (*i)->v_position() << "\""
- << ">" << escape ((*i)->text()) << "</Text>\n";
-
- first = false;
+ xmlpp::Element* text = subtitle->add_child ("Text");
+ text->set_attribute ("VAlign", valign_to_string ((*i)->v_align()));
+ text->set_attribute ("VPosition", lexical_cast<string> ((*i)->v_position()));
+ text->add_child_text ((*i)->text());
}
- s << " </Subtitle>\n";
- s << " </Font>\n";
- s << "</DCSubtitle>\n";
+ doc.write_to_stream_formatted (s);
}
-/** XXX: Another reason why we should be writing with libxml++ */
-string
-SubtitleAsset::escape (string s) const
-{
- boost::replace_all (s, "&", "&");
- return s;
-}
SubtitleAsset (std::string directory, std::string xml_file);
SubtitleAsset (std::string directory, std::string movie_title, std::string language);
- void write_to_cpl (std::ostream&) const;
+ void write_to_cpl (xmlpp::Node *) const;
virtual bool equals (boost::shared_ptr<const Asset>, EqualityOptions, boost::function<void (NoteType, std::string)> note) const {
/* XXX */
note (ERROR, "subtitle assets not compared yet");
void read_xml (std::string);
void write_xml () const;
- void write_xml (std::ostream& s) const;
+ void write_xml (std::ostream &) const;
private:
std::string font_id_to_name (std::string id) const;
- std::string escape (std::string) const;
struct ParseState {
std::list<boost::shared_ptr<parse::Font> > font_nodes;