Support horizontal alignment specification in subtitles.
authorCarl Hetherington <cth@carlh.net>
Fri, 16 Jan 2015 10:35:44 +0000 (10:35 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 16 Jan 2015 10:35:44 +0000 (10:35 +0000)
src/parse/subtitle.cc
src/parse/subtitle.h
src/subtitle_asset.cc
src/subtitle_asset.h
src/types.cc
src/types.h
test/subtitle_tests.cc
tools/dcpinfo.cc

index 56222c973473d076c03e3699487c4fb94b28f07c..8c53bd6819db8d775d6930d71c6f469e108c39aa 100644 (file)
@@ -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)));
index 867b3f0e3f6ecfe3498bf212f186410c785f7ecc..3993a6bea1df699bf4d27d92e89da860b5fdfa60 100644 (file)
@@ -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;
 };
index 100f6a4e3aacd261a03d603d0342cb4949ce2fc5..0e76a62d734ee1a044e9376414021c0c33cd7013 100644 (file)
@@ -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());
        }
index a5014307521b32c824aaa240b4f0a68395d601c4..335b9f37b0af22c3456b12b003348339d34e2d1a 100644 (file)
@@ -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;
index f45e3345b8b5894c62a14dbf5ed44de98333b7aa..920cc5e9866f4b46bc2d92815639bddbbed42750 100644 (file)
@@ -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"));
+}
index 013c18630847bc02d5c9930466753b906542ecb2..e02c36ebfec5d9682a7573a4a50d0fd0a9550f6a 100644 (file)
@@ -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,
index d1b2795fcd18e6269ad207dec58bbbfc3f2fb417..8f0b08559791d741dc7bf6dce0a2b083a0ceee0f 100644 (file)
@@ -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),
index 59e676f69dd7f3354f60ca7cc26255630aad78cd..e36153d80b039b520c624de38739696f07e00657 100644 (file)
@@ -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() << "; "