summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarl Hetherington <cth@carlh.net>2015-01-16 10:35:44 +0000
committerCarl Hetherington <cth@carlh.net>2015-01-16 10:35:44 +0000
commitee03fd414e2c6e3dd398107ceb4ee365ff427adc (patch)
treeff1450b622a1dbbee751bcbe5b829c21f8d144c6
parentd67d3fc2281c7d83ff2a4e3913f63022bd5f8f16 (diff)
Support horizontal alignment specification in subtitles.
-rw-r--r--src/parse/subtitle.cc12
-rw-r--r--src/parse/subtitle.h3
-rw-r--r--src/subtitle_asset.cc11
-rw-r--r--src/subtitle_asset.h6
-rw-r--r--src/types.cc41
-rw-r--r--src/types.h16
-rw-r--r--test/subtitle_tests.cc75
-rw-r--r--tools/dcpinfo.cc1
8 files changed, 126 insertions, 39 deletions
diff --git a/src/parse/subtitle.cc b/src/parse/subtitle.cc
index 56222c97..8c53bd68 100644
--- a/src/parse/subtitle.cc
+++ b/src/parse/subtitle.cc
@@ -147,7 +147,8 @@ Subtitle::fade_time (shared_ptr<const cxml::Node> node, string name, optional<in
}
Text::Text (shared_ptr<const cxml::Node> node, optional<int> tcr)
- : v_align (CENTER)
+ : v_align (VERTICAL_CENTER)
+ , h_align (HORIZONTAL_CENTER)
{
/* Vertical position */
text = node->content ();
@@ -166,6 +167,15 @@ Text::Text (shared_ptr<const cxml::Node> node, optional<int> tcr)
v_align = string_to_valign (v.get ());
}
+ /* Horizontal alignment */
+ optional<string> h = node->optional_string_attribute ("HAlign");
+ if (!h) {
+ h = node->optional_string_attribute ("Halign");
+ }
+ if (h) {
+ h_align = string_to_halign (h.get ());
+ }
+
list<cxml::NodePtr> f = node->node_children ("Font");
for (list<cxml::NodePtr>::iterator i = f.begin(); i != f.end(); ++i) {
font_nodes.push_back (shared_ptr<Font> (new Font (*i, tcr)));
diff --git a/src/parse/subtitle.h b/src/parse/subtitle.h
index 867b3f0e..3993a6be 100644
--- a/src/parse/subtitle.h
+++ b/src/parse/subtitle.h
@@ -34,13 +34,14 @@ class Text
public:
Text ()
: v_position (0)
- , v_align (TOP)
+ , v_align (VERTICAL_TOP)
{}
Text (boost::shared_ptr<const cxml::Node> node, boost::optional<int> tcr);
float v_position;
VAlign v_align;
+ HAlign h_align;
std::string text;
std::list<boost::shared_ptr<Font> > font_nodes;
};
diff --git a/src/subtitle_asset.cc b/src/subtitle_asset.cc
index 100f6a4e..0e76a62d 100644
--- a/src/subtitle_asset.cc
+++ b/src/subtitle_asset.cc
@@ -192,7 +192,8 @@ SubtitleAsset::maybe_add_subtitle (string text, ParseState& parse_state)
effective_subtitle.in != c->in() ||
effective_subtitle.out != c->out() ||
effective_text.v_position != c->v_position() ||
- effective_text.v_align != c->v_align()) {
+ effective_text.v_align != c->v_align() ||
+ effective_text.h_align != c->h_align()) {
parse_state.current.reset (
new Subtitle (
@@ -204,6 +205,7 @@ SubtitleAsset::maybe_add_subtitle (string text, ParseState& parse_state)
effective_subtitle.out,
effective_text.v_position,
effective_text.v_align,
+ effective_text.h_align,
"",
effective_font.effect ? effective_font.effect.get() : NONE,
effective_font.effect_color.get(),
@@ -263,6 +265,7 @@ Subtitle::Subtitle (
Time out,
float v_position,
VAlign v_align,
+ HAlign h_align,
string text,
Effect effect,
Color effect_color,
@@ -277,6 +280,7 @@ Subtitle::Subtitle (
, _out (out)
, _v_position (v_position)
, _v_align (v_align)
+ , _h_align (h_align)
, _text (text)
, _effect (effect)
, _effect_color (effect_color)
@@ -309,6 +313,7 @@ libdcp::operator== (Subtitle const & a, Subtitle const & b)
a.out() == b.out() &&
a.v_position() == b.v_position() &&
a.v_align() == b.v_align() &&
+ a.h_align() == b.h_align() &&
a.text() == b.text() &&
a.effect() == b.effect() &&
a.effect_color() == b.effect_color() &&
@@ -330,7 +335,8 @@ libdcp::operator<< (ostream& s, Subtitle const & sub)
s << "non-italic";
}
- s << ", size " << sub.size() << ", color " << sub.color() << ", vpos " << sub.v_position() << ", valign " << ((int) sub.v_align()) << ";\n"
+ s << ", size " << sub.size() << ", color " << sub.color()
+ << ", vpos " << sub.v_position() << ", valign " << ((int) sub.v_align()) << ", halign " << ((int) sub.h_align()) << "; "
<< "effect " << ((int) sub.effect()) << ", effect color " << sub.effect_color();
return s;
@@ -482,6 +488,7 @@ SubtitleAsset::xml_as_string () const
xmlpp::Element* text = subtitle->add_child ("Text");
text->set_attribute ("VAlign", valign_to_string ((*i)->v_align()));
+ text->set_attribute ("HAlign", halign_to_string ((*i)->h_align()));
text->set_attribute ("VPosition", raw_convert<string> ((*i)->v_position()));
text->add_child_text ((*i)->text());
}
diff --git a/src/subtitle_asset.h b/src/subtitle_asset.h
index a5014307..335b9f37 100644
--- a/src/subtitle_asset.h
+++ b/src/subtitle_asset.h
@@ -47,6 +47,7 @@ public:
Time out,
float v_position,
VAlign v_align,
+ HAlign h_align,
std::string text,
Effect effect,
Color effect_color,
@@ -90,6 +91,10 @@ public:
return _v_align;
}
+ HAlign h_align () const {
+ return _h_align;
+ }
+
Effect effect () const {
return _effect;
}
@@ -127,6 +132,7 @@ private:
*/
float _v_position;
VAlign _v_align;
+ HAlign _h_align;
std::string _text;
Effect _effect;
Color _effect_color;
diff --git a/src/types.cc b/src/types.cc
index f45e3345..920cc5e9 100644
--- a/src/types.cc
+++ b/src/types.cc
@@ -159,11 +159,11 @@ string
libdcp::valign_to_string (VAlign v)
{
switch (v) {
- case TOP:
+ case VERTICAL_TOP:
return "top";
- case CENTER:
+ case VERTICAL_CENTER:
return "center";
- case BOTTOM:
+ case VERTICAL_BOTTOM:
return "bottom";
}
@@ -174,14 +174,41 @@ VAlign
libdcp::string_to_valign (string s)
{
if (s == "top") {
- return TOP;
+ return VERTICAL_TOP;
} else if (s == "center") {
- return CENTER;
+ return VERTICAL_CENTER;
} else if (s == "bottom") {
- return BOTTOM;
+ return VERTICAL_BOTTOM;
}
boost::throw_exception (DCPReadError ("unknown subtitle valign type"));
}
-
+string
+libdcp::halign_to_string (HAlign h)
+{
+ switch (h) {
+ case HORIZONTAL_LEFT:
+ return "left";
+ case HORIZONTAL_CENTER:
+ return "center";
+ case HORIZONTAL_RIGHT:
+ return "right";
+ }
+
+ boost::throw_exception (MiscError ("unknown halign type"));
+}
+
+HAlign
+libdcp::string_to_halign (string s)
+{
+ if (s == "left") {
+ return HORIZONTAL_LEFT;
+ } else if (s == "center") {
+ return HORIZONTAL_CENTER;
+ } else if (s == "right") {
+ return HORIZONTAL_RIGHT;
+ }
+
+ boost::throw_exception (DCPReadError ("unknown subtitle halign type"));
+}
diff --git a/src/types.h b/src/types.h
index 013c1863..e02c36eb 100644
--- a/src/types.h
+++ b/src/types.h
@@ -72,14 +72,24 @@ extern Effect string_to_effect (std::string s);
enum VAlign
{
- TOP,
- CENTER,
- BOTTOM
+ VERTICAL_TOP,
+ VERTICAL_CENTER,
+ VERTICAL_BOTTOM
};
extern std::string valign_to_string (VAlign a);
extern VAlign string_to_valign (std::string s);
+enum HAlign
+{
+ HORIZONTAL_LEFT,
+ HORIZONTAL_CENTER,
+ HORIZONTAL_RIGHT
+};
+
+extern std::string halign_to_string (HAlign a);
+extern HAlign string_to_halign (std::string s);
+
enum Eye
{
EYE_LEFT,
diff --git a/test/subtitle_tests.cc b/test/subtitle_tests.cc
index d1b2795f..8f0b0855 100644
--- a/test/subtitle_tests.cc
+++ b/test/subtitle_tests.cc
@@ -40,7 +40,8 @@ BOOST_AUTO_TEST_CASE (subtitles1)
libdcp::Time (0, 0, 5, 198, 250),
libdcp::Time (0, 0, 7, 115, 250),
15,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"My jacket was Idi Amin's",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -58,7 +59,8 @@ BOOST_AUTO_TEST_CASE (subtitles1)
libdcp::Time (0, 0, 7, 177, 250),
libdcp::Time (0, 0, 11, 31, 250),
21,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"My corset was H.M. The Queen's",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -73,7 +75,8 @@ BOOST_AUTO_TEST_CASE (subtitles1)
libdcp::Time (0, 0, 7, 177, 250),
libdcp::Time (0, 0, 11, 31, 250),
15,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"My large wonderbra",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -91,7 +94,8 @@ BOOST_AUTO_TEST_CASE (subtitles1)
libdcp::Time (0, 0, 11, 94, 250),
libdcp::Time (0, 0, 13, 63, 250),
15,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"Once belonged to the Shah",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -109,7 +113,8 @@ BOOST_AUTO_TEST_CASE (subtitles1)
libdcp::Time (0, 0, 13, 104, 250),
libdcp::Time (0, 0, 15, 177, 250),
15,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"And these are Roy Hattersley's jeans",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -133,7 +138,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 0, 41, 62, 250),
libdcp::Time (0, 0, 43, 52, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"At afternoon tea with John Peel",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -148,7 +154,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 0, 41, 62, 250),
libdcp::Time (0, 0, 43, 52, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"I enquired if his accent was real",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -166,7 +173,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 0, 50, 42, 250),
libdcp::Time (0, 0, 52, 21, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"He said \"out of the house",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -181,7 +189,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 0, 50, 42, 250),
libdcp::Time (0, 0, 52, 21, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"I'm incredibly scouse",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -199,7 +208,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 2, 208, 250),
libdcp::Time (0, 1, 4, 10, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"At home it depends how I feel.\"",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -214,7 +224,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 2, 208, 250),
libdcp::Time (0, 1, 4, 10, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"I spent a long weekend in Brighton",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -232,7 +243,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 15, 42, 250),
libdcp::Time (0, 1, 16, 42, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"With the legendary Miss Enid Blyton",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -247,7 +259,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 15, 42, 250),
libdcp::Time (0, 1, 16, 42, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"She said \"you be Noddy",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -265,7 +278,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 27, 115, 250),
libdcp::Time (0, 1, 28, 208, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"That curious creature the Sphinx",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -280,7 +294,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 27, 115, 250),
libdcp::Time (0, 1, 28, 208, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"Is smarter than anyone thinks",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -298,7 +313,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 42, 229, 250),
libdcp::Time (0, 1, 45, 62, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"It sits there and smirks",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -313,7 +329,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 42, 229, 250),
libdcp::Time (0, 1, 45, 62, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"And you don't think it works",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -331,7 +348,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 45, 146, 250),
libdcp::Time (0, 1, 47, 94, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"Then when you're not looking, it winks.",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -346,7 +364,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 45, 146, 250),
libdcp::Time (0, 1, 47, 94, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"When it snows you will find Sister Sledge",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -364,7 +383,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 47, 146, 250),
libdcp::Time (0, 1, 48, 167, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"Out mooning, at night, on the ledge",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -379,7 +399,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 1, 47, 146, 250),
libdcp::Time (0, 1, 48, 167, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"One storey down",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -397,7 +418,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 2, 5, 208, 250),
libdcp::Time (0, 2, 7, 31, 250),
89,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"HELLO",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -412,7 +434,8 @@ BOOST_AUTO_TEST_CASE (subtitles2)
libdcp::Time (0, 2, 5, 208, 250),
libdcp::Time (0, 2, 7, 31, 250),
95,
- libdcp::TOP,
+ libdcp::VERTICAL_TOP,
+ libdcp::HORIZONTAL_CENTER,
"WORLD",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -437,7 +460,8 @@ BOOST_AUTO_TEST_CASE (subtitles3)
libdcp::Time (0, 0, 4, 21, 25),
libdcp::Time (0, 0, 6, 5, 25),
8,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"Hello world",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
@@ -462,7 +486,8 @@ BOOST_AUTO_TEST_CASE (subtitles4)
libdcp::Time (0, 0, 4, 21, 25),
libdcp::Time (0, 0, 6, 5, 25),
8,
- libdcp::BOTTOM,
+ libdcp::VERTICAL_BOTTOM,
+ libdcp::HORIZONTAL_CENTER,
"Hello <i>there</i> world",
libdcp::BORDER,
libdcp::Color (0, 0, 0),
diff --git a/tools/dcpinfo.cc b/tools/dcpinfo.cc
index 59e676f6..e36153d8 100644
--- a/tools/dcpinfo.cc
+++ b/tools/dcpinfo.cc
@@ -111,6 +111,7 @@ main (int argc, char* argv[])
<< "out:" << (*k)->out() << "; "
<< "v_position:" << (*k)->v_position() << "; "
<< "v_align:" << (*k)->v_align() << "; "
+ << "h_align:" << (*k)->h_align() << "; "
<< "effect:" << (*k)->effect() << "; "
<< "effect_color:" << (*k)->effect_color() << "; "
<< "fade_up_time:" << (*k)->fade_up_time() << "; "