--- /dev/null
+/*
+ Copyright (C) 2023 Carl Hetherington <cth@carlh.net>
+
+ This file is part of libdcp.
+
+ libdcp is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ libdcp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libdcp. If not, see <http://www.gnu.org/licenses/>.
+
+ 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 "ruby.h"
+#include "types.h"
+
+
+using namespace dcp;
+
+
+bool dcp::operator==(Ruby const& a, Ruby const& b)
+{
+ return a.base == b.base &&
+ a.annotation == b.annotation &&
+ fabs(a.size - b.size) < SIZE_EPSILON &&
+ a. position == b.position &&
+ fabs(a.offset - b.offset) < OFFSET_EPSILON &&
+ fabs(a.spacing - b.spacing) < SPACING_EPSILON &&
+ fabs(a.aspect_adjust - b.aspect_adjust) < ASPECT_ADJUST_EPSILON;
+}
+
+
+bool dcp::operator!=(Ruby const& a, Ruby const& b)
+{
+ return !(a == b);
+}
--- /dev/null
+/*
+ Copyright (C) 2023 Carl Hetherington <cth@carlh.net>
+
+ This file is part of libdcp.
+
+ libdcp is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ libdcp is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with libdcp. If not, see <http://www.gnu.org/licenses/>.
+
+ 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 <string>
+
+
+namespace dcp {
+
+
+enum class RubyPosition
+{
+ BEFORE,
+ AFTER
+};
+
+
+class Ruby
+{
+public:
+ Ruby(std::string base_, std::string annotation_)
+ : base(base_)
+ , annotation(annotation_)
+ {}
+
+ std::string base;
+ std::string annotation;
+ float size = 0.5;
+ RubyPosition position = RubyPosition::BEFORE;
+ float offset = 0;
+ float spacing = 0;
+ float aspect_adjust = 1;
+};
+
+
+bool operator==(Ruby const& a, Ruby const& b);
+bool operator!=(Ruby const& a, Ruby const& b);
+
+
+}
+
float space_before = 0;
+ /* Collect <Ruby>s first */
+ auto get_text_content = [](xmlpp::Element const* element) {
+ string all_content;
+ for (auto child: element->get_children()) {
+ auto content = dynamic_cast<xmlpp::ContentNode const*>(child);
+ if (content) {
+ all_content += content->get_content();
+ }
+ }
+ return all_content;
+ };
+
+ vector<Ruby> rubies;
+ for (auto child: node->get_children()) {
+ auto element = dynamic_cast<xmlpp::Element const*>(child);
+ if (element && element->get_name() == "Ruby") {
+ optional<string> base;
+ optional<string> annotation;
+ optional<float> size;
+ optional<RubyPosition> position;
+ optional<float> offset;
+ optional<float> spacing;
+ optional<float> aspect_adjust;
+ for (auto ruby_child: element->get_children()) {
+ if (auto ruby_element = dynamic_cast<xmlpp::Element const*>(ruby_child)) {
+ if (ruby_element->get_name() == "Rb") {
+ base = get_text_content(ruby_element);
+ } else if (ruby_element->get_name() == "Rt") {
+ annotation = get_text_content(ruby_element);
+ size = optional_number_attribute<float>(ruby_element, "Size");
+ if (auto position_string = optional_string_attribute(ruby_element, "Position")) {
+ if (*position_string == "before") {
+ position = RubyPosition::BEFORE;
+ } else if (*position_string == "after") {
+ position = RubyPosition::AFTER;
+ } else {
+ DCP_ASSERT(false);
+ }
+ }
+ offset = optional_number_attribute<float>(ruby_element, "Offset");
+ spacing = optional_number_attribute<float>(ruby_element, "Spacing");
+ aspect_adjust = optional_number_attribute<float>(ruby_element, "AspectAdjust");
+ }
+ }
+ }
+ DCP_ASSERT(base);
+ DCP_ASSERT(annotation);
+ auto ruby = Ruby{*base, *annotation};
+ if (size) {
+ ruby.size = *size;
+ }
+ if (position) {
+ ruby.position = *position;
+ }
+ if (offset) {
+ ruby.offset = *offset;
+ }
+ if (spacing) {
+ ruby.spacing = *spacing;
+ }
+ if (aspect_adjust) {
+ ruby.aspect_adjust = *aspect_adjust;
+ }
+ rubies.push_back(ruby);
+ }
+ }
+
for (auto i: node->get_children()) {
+
+ /* Handle actual content e.g. text */
auto const v = dynamic_cast<xmlpp::ContentNode const *>(i);
if (v) {
- maybe_add_subtitle (v->get_content(), state, space_before, standard);
+ maybe_add_subtitle (v->get_content(), state, space_before, standard, rubies);
space_before = 0;
}
+
+ /* Handle other nodes */
auto const e = dynamic_cast<xmlpp::Element const *>(i);
if (e) {
if (e->get_name() == "Space") {
boost::replace_all(size, "em", "");
}
space_before += raw_convert<float>(size);
- } else {
+ } else if (e->get_name() != "Ruby") {
parse_subtitles (e, state, tcr, standard);
}
}
void
-SubtitleAsset::maybe_add_subtitle (string text, vector<ParseState> const & parse_state, float space_before, Standard standard)
+SubtitleAsset::maybe_add_subtitle(
+ string text,
+ vector<ParseState> const & parse_state,
+ float space_before,
+ Standard standard,
+ vector<Ruby> const& rubies
+ )
{
auto wanted = [](ParseState const& ps) {
return ps.type && (ps.type.get() == ParseState::Type::TEXT || ps.type.get() == ParseState::Type::IMAGE);
ps.effect_colour.get_value_or (dcp::Colour (0, 0, 0)),
ps.fade_up_time.get_value_or(Time()),
ps.fade_down_time.get_value_or(Time()),
- space_before
+ space_before,
+ rubies
)
);
break;
fabs(last_z_position - is->z_position()) > ALIGN_EPSILON ||
last_direction != is->direction()
) {
- text = make_shared<order::Text>(subtitle, is->h_align(), is->h_position(), is->v_align(), is->v_position(), is->z_position(), is->direction());
+ text = make_shared<order::Text>(
+ subtitle,
+ is->h_align(),
+ is->h_position(),
+ is->v_align(),
+ is->v_position(),
+ is->z_position(),
+ is->direction(),
+ is->rubies()
+ );
subtitle->children.push_back (text);
last_h_align = is->h_align ();
friend struct ::pull_fonts_test2;
friend struct ::pull_fonts_test3;
- void maybe_add_subtitle (std::string text, std::vector<ParseState> const & parse_state, float space_before, Standard standard);
+ void maybe_add_subtitle(
+ std::string text,
+ std::vector<ParseState> const & parse_state,
+ float space_before,
+ Standard standard,
+ std::vector<Ruby> const& rubies
+ );
static void pull_fonts (std::shared_ptr<order::Part> part);
};
e->set_attribute ("Direction", direction_to_string (_direction));
}
+ for (auto const& ruby: _rubies) {
+ auto xml = e->add_child("Ruby");
+ xml->add_child("Rb")->add_child_text(ruby.base);
+ auto rt = xml->add_child("Rt");
+ rt->add_child_text(ruby.annotation);
+ rt->set_attribute("Size", dcp::raw_convert<string>(ruby.size, 6));
+ rt->set_attribute("Position", ruby.position == RubyPosition::BEFORE ? "before" : "after");
+ rt->set_attribute("Offset", dcp::raw_convert<string>(ruby.offset, 6));
+ rt->set_attribute("Spacing", dcp::raw_convert<string>(ruby.spacing, 6));
+ rt->set_attribute("AspectAdjust", dcp::raw_convert<string>(ruby.aspect_adjust, 6));
+ }
+
return e;
}
namespace dcp {
+class Ruby;
class SubtitleString;
class Text : public Part
{
public:
- Text (std::shared_ptr<Part> parent, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position, Direction direction)
+ Text(std::shared_ptr<Part> parent, HAlign h_align, float h_position, VAlign v_align, float v_position, float z_position, Direction direction, std::vector<Ruby> rubies)
: Part (parent)
, _h_align (h_align)
, _h_position (h_position)
, _v_position (v_position)
, _z_position(z_position)
, _direction (direction)
+ , _rubies(rubies)
{}
xmlpp::Element* as_xml (xmlpp::Element* parent, Context& context) const override;
float _v_position;
float _z_position;
Direction _direction;
+ std::vector<Ruby> _rubies;
};
using std::ostream;
using std::shared_ptr;
using std::string;
+using std::vector;
using boost::optional;
using namespace dcp;
Colour effect_colour,
Time fade_up_time,
Time fade_down_time,
- float space_before
+ float space_before,
+ vector<Ruby> rubies
)
: Subtitle(in, out, h_position, h_align, v_position, v_align, z_position, fade_up_time, fade_down_time)
, _font (font)
, _effect (effect)
, _effect_colour (effect_colour)
, _space_before (space_before)
+ , _rubies(rubies)
{
_aspect_adjust = max(min(_aspect_adjust, 4.0f), 0.25f);
}
a.effect_colour() == b.effect_colour() &&
a.fade_up_time() == b.fade_up_time() &&
a.fade_down_time() == b.fade_down_time() &&
- fabs (a.space_before() - b.space_before()) < SPACE_BEFORE_EPSILON
+ fabs (a.space_before() - b.space_before()) < SPACE_BEFORE_EPSILON &&
+ a.rubies() == b.rubies()
);
}
<< ", effect colour (" << sub.effect_colour().r << ", " << sub.effect_colour().g << ", " << sub.effect_colour().b << ")"
<< ", space before " << sub.space_before();
+ for (auto ruby: sub.rubies()) {
+ s << ", ruby " << ruby.base << " " << ruby.annotation;
+ }
+
return s;
}
same = false;
}
+ if (_rubies != other->_rubies) {
+ note(NoteType::ERROR, "rubies differ");
+ same = false;
+ }
+
return same;
}
#include "dcp_time.h"
+#include "ruby.h"
#include "subtitle.h"
#include <boost/optional.hpp>
#include <string>
Colour effect_colour,
Time fade_up_time,
Time fade_down_time,
- float space_before
+ float space_before,
+ std::vector<Ruby> rubies
);
/** @return font ID */
return _aspect_adjust;
}
+ std::vector<Ruby> const& rubies() const {
+ return _rubies;
+ }
+
void set_font (std::string id) {
_font = id;
}
_effect_colour = c;
}
+ void set_rubies(std::vector<Ruby> rubies) {
+ _rubies = std::move(rubies);
+ }
+
bool equals(std::shared_ptr<const dcp::Subtitle> other_sub, EqualityOptions const& options, NoteHandler node) const override;
private:
Effect _effect;
Colour _effect_colour;
float _space_before;
+ std::vector<Ruby> _rubies;
};
bool operator== (SubtitleString const & a, SubtitleString const & b);
#endif
+
constexpr float SPACE_BEFORE_EPSILON = 1e-3;
+constexpr float SIZE_EPSILON = 1e-3;
+constexpr float OFFSET_EPSILON = 1e-3;
+constexpr float SPACING_EPSILON = 1e-3;
+
+
enum class Marker {
FFOC, ///< first frame of composition
LFOC, ///< last frame of composition
reel_subtitle_asset.cc
ref.cc
rgb_xyz.cc
+ ruby.cc
s_gamut3_transfer_function.cc
search.cc
smpte_load_font_node.cc
reel_stereo_picture_asset.h
reel_subtitle_asset.h
ref.h
+ ruby.h
s_gamut3_transfer_function.h
search.h
smpte_load_font_node.h
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<DCSubtitle Version="1.0">
+ <SubtitleID>cab5c268-222b-41d2-88ae-6d6999441b17</SubtitleID>
+ <MovieTitle>Movie Title</MovieTitle>
+ <ReelNumber>1</ReelNumber>
+ <Language>French</Language>
+ <LoadFont Id="theFontId" URI="arial.ttf"/>
+ <Font AspectAdjust="1.0" Color="FFFFFFFF" Effect="border" EffectColor="FF000000" Id="theFontId" Italic="no" Script="normal" Size="39" Underlined="no" Weight="normal">
+ <Subtitle SpotNumber="1" TimeIn="00:00:05:198" TimeOut="00:00:07:115" FadeUpTime="1" FadeDownTime="1">
+ <Text VAlign="center" VPosition="0"><Ruby><Rb>Base</Rb><Rt Size="0.7" Position="after" Offset="0.1" Spacing="0.4" AspectAdjust="0.9">Annotate</Rt></Ruby>Hello world</Text>
+ </Subtitle>
+ </Font>
+</DCSubtitle>
+
"Hello world",
dcp::Effect::NONE,
dcp::Colour(0, 0, 0),
- dcp::Time(), dcp::Time(), 0
+ dcp::Time(), dcp::Time(), 0, std::vector<dcp::Ruby>()
));
subs_asset->write (dir / "subs.mxf");
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 6
+ 6,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 0, 7, 190, 250), dcp::Time (0, 0, 7, 191, 250), false);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 0, 11, 95, 250), dcp::Time (0, 0, 11, 96, 250), false);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 0, 14, 42, 250), dcp::Time (0, 0, 14, 43, 250), false);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 1, 250),
dcp::Time (0, 0, 0, 1, 250),
- 0
+ 0,
+ {}
));
}
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 250),
dcp::Time (0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 250),
dcp::Time (0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 0, 50, 50, 250), dcp::Time (0, 0, 50, 51, 250), false);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 250),
dcp::Time (0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 250),
dcp::Time (0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 2, 300, 250), dcp::Time (0, 1, 2, 301, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 15, 50, 250), dcp::Time (0, 1, 15, 51, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 27, 200, 250), dcp::Time (0, 1, 27, 201, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 42, 300, 250), dcp::Time (0, 1, 42, 301, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 45, 200, 250), dcp::Time (0, 1, 45, 201, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 1, 47, 249, 250), dcp::Time (0, 1, 47, 250, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
s = subs.subtitles_during (dcp::Time (0, 2, 6, 210, 250), dcp::Time (0, 2, 6, 211, 250), false);
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
BOOST_REQUIRE (dynamic_pointer_cast<const dcp::SubtitleString>(s.back()));
BOOST_CHECK_EQUAL (*dynamic_pointer_cast<const dcp::SubtitleString>(s.back()), dcp::SubtitleString (
dcp::Colour(0, 0, 0),
dcp::Time(0, 0, 0, 0, 250),
dcp::Time(0, 0, 0, 0, 250),
- 0
+ 0,
+ {}
));
}
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (1, 2, 3),
dcp::Time (1, 2, 3, 4, 24),
dcp::Time (5, 6, 7, 8, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (1, 2, 3),
dcp::Time (1, 2, 3, 4, 24),
dcp::Time (5, 6, 7, 8, 24),
- 9
+ 9,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (1, 2, 3),
dcp::Time (1, 2, 3, 4, 24),
dcp::Time (5, 6, 7, 8, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
auto root = make_shared<dcp::order::Part>(shared_ptr<dcp::order::Part>());
auto sub1 = make_shared<dcp::order::Subtitle>(root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time());
root->children.push_back (sub1);
- auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR);
+ auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR, std::vector<dcp::Ruby>());
sub1->children.push_back (text1);
text1->font._values["font"] = "Inconsolata";
text1->font._values["size"] = "42";
auto root = make_shared<dcp::order::Part>(shared_ptr<dcp::order::Part> ());
auto sub1 = make_shared<dcp::order::Subtitle>(root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time());
root->children.push_back (sub1);
- auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR);
+ auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR, std::vector<dcp::Ruby>());
sub1->children.push_back (text1);
text1->font._values["font"] = "Inconsolata";
text1->font._values["size"] = "42";
- auto text2 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR);
+ auto text2 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR, std::vector<dcp::Ruby>());
sub1->children.push_back (text2);
text2->font._values["font"] = "Inconsolata";
text2->font._values["size"] = "48";
auto root = make_shared<dcp::order::Part>(shared_ptr<dcp::order::Part> ());
auto sub1 = make_shared<dcp::order::Subtitle>(root, dcp::Time(), dcp::Time(), dcp::Time(), dcp::Time());
root->children.push_back (sub1);
- auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR);
+ auto text1 = make_shared<dcp::order::Text>(sub1, dcp::HAlign::CENTER, 0, dcp::VAlign::TOP, 0, 0, dcp::Direction::LTR, std::vector<dcp::Ruby>());
sub1->children.push_back (text1);
dcp::order::Font font;
font._values["font"] = "Inconsolata";
" <Bar>Don't panic &amp; xml \"is\" 'great' & < > —</Bar>\n"
"</Foo>\n");
}
+
+
+BOOST_AUTO_TEST_CASE(ruby_round_trip_test)
+{
+ dcp::InteropSubtitleAsset asset("test/data/ruby1.xml");
+ check_xml(dcp::file_to_string("test/data/ruby1.xml"), asset.xml_as_string(), {}, false);
+}
+
+
dcp::Colour(),
dcp::Time(0, 0, 0, 0, 24),
dcp::Time(0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
subs.write("build/test/smpte_subtitle_id_test.mxf");
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (1, 2, 3),
dcp::Time (1, 2, 3, 4, 24),
dcp::Time (5, 6, 7, 8, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (1, 2, 3),
dcp::Time (1, 2, 3, 4, 24),
dcp::Time (5, 6, 7, 8, 24),
- 4.2
+ 4.2,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour (0, 0, 0),
dcp::Time (0, 0, 0, 0, 24),
dcp::Time (0, 0, 0, 0, 24),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
dcp::Colour(255, 255, 255),
dcp::Time(),
dcp::Time(),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
);
}
dcp::Colour(),
dcp::Time(),
dcp::Time(),
- 0
+ 0,
+ std::vector<dcp::Ruby>()
)
);
}