Support underlining of subtitles.
authorCarl Hetherington <cth@carlh.net>
Fri, 24 Jun 2016 11:24:16 +0000 (12:24 +0100)
committerCarl Hetherington <cth@carlh.net>
Fri, 24 Jun 2016 11:24:16 +0000 (12:24 +0100)
src/font_node.cc
src/font_node.h
src/subtitle_asset.cc
src/subtitle_string.cc
src/subtitle_string.h
test/data/subs1.xml
test/read_interop_subtitle_test.cc
test/write_subtitle_test.cc

index c24c29d6580240bcac350f9c313ffb93f13df247..1aa4be6bfa44978ff9c6eed9675d2fdaed2fee0b 100644 (file)
@@ -58,6 +58,11 @@ FontNode::FontNode (cxml::ConstNodePtr node, optional<int> tcr, Standard standar
        aspect_adjust = node->optional_number_attribute<float> ("AspectAdjust");
        italic = node->optional_bool_attribute ("Italic");
        bold = node->optional_string_attribute("Weight").get_value_or("normal") == "bold";
+       if (standard == INTEROP) {
+               underline = node->optional_bool_attribute ("Underlined");
+       } else {
+               underline = node->optional_bool_attribute ("Underline");
+       }
        optional<string> c = node->optional_string_attribute ("Color");
        if (c) {
                colour = Colour (c.get ());
@@ -91,6 +96,7 @@ FontNode::FontNode (std::list<boost::shared_ptr<FontNode> > const & font_nodes)
        : size (0)
        , italic (false)
        , bold (false)
+       , underline (false)
        , colour ("FFFFFFFF")
        , effect_colour ("FFFFFFFF")
 {
@@ -110,6 +116,9 @@ FontNode::FontNode (std::list<boost::shared_ptr<FontNode> > const & font_nodes)
                if ((*i)->bold) {
                        bold = (*i)->bold.get ();
                }
+               if ((*i)->underline) {
+                       underline = (*i)->underline.get ();
+               }
                if ((*i)->colour) {
                        colour = (*i)->colour.get ();
                }
index 656c026440f4142ed8937d643445bc1a09579120..2108af9e5b93a6380d27c46faccefe600052a09c 100644 (file)
@@ -63,6 +63,7 @@ public:
        boost::optional<float> aspect_adjust;
        boost::optional<bool> italic;
        boost::optional<bool> bold;
+       boost::optional<bool> underline;
        boost::optional<Colour> colour;
        boost::optional<Effect> effect;
        boost::optional<Colour> effect_colour;
index f1365118bc71cfd036030b74308ed8be309a52d3..35ca6174672069e05512d5ed8b919adcc0f0c4cd 100644 (file)
@@ -158,6 +158,7 @@ SubtitleAsset::maybe_add_subtitle (string text, ParseState const & parse_state)
                        effective_font.id,
                        effective_font.italic.get_value_or (false),
                        effective_font.bold.get_value_or (false),
+                       effective_font.underline.get_value_or (false),
                        effective_font.colour.get_value_or (dcp::Colour (255, 255, 255)),
                        effective_font.size,
                        effective_font.aspect_adjust.get_value_or (1.0),
@@ -249,11 +250,12 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Stand
 
        string const xmlns = standard == SMPTE ? "dcst" : "";
 
-       /* XXX: script, underlined not supported */
+       /* XXX: script not supported */
 
        optional<string> font;
        bool italic = false;
        bool bold = false;
+       bool underline = false;
        Colour colour;
        int size = 0;
        float aspect_adjust = 1.0;
@@ -279,6 +281,7 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Stand
                        font          != i.font()          ||
                        italic        != i.italic()        ||
                        bold          != i.bold()          ||
+                       underline     != i.underline()     ||
                        colour        != i.colour()        ||
                        size          != i.size()          ||
                        fabs (aspect_adjust - i.aspect_adjust()) > ASPECT_ADJUST_EPSILON ||
@@ -289,6 +292,7 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Stand
                        font = i.font ();
                        italic = i.italic ();
                        bold = i.bold ();
+                       underline = i.underline ();
                        colour = i.colour ();
                        size = i.size ();
                        aspect_adjust = i.aspect_adjust ();
@@ -315,9 +319,9 @@ SubtitleAsset::subtitles_as_xml (xmlpp::Element* root, int time_code_rate, Stand
                        font_element->set_attribute ("EffectColor", effect_colour.to_argb_string());
                        font_element->set_attribute ("Script", "normal");
                        if (standard == SMPTE) {
-                               font_element->set_attribute ("Underline", "no");
+                               font_element->set_attribute ("Underline", underline ? "yes" : "no");
                        } else {
-                               font_element->set_attribute ("Underlined", "no");
+                               font_element->set_attribute ("Underlined", underline ? "yes" : "no");
                        }
                        font_element->set_attribute ("Weight", bold ? "bold" : "normal");
                }
index 8e106c6df78dee5d920b6d0d01e054345c9dc73e..5a22475c65ff9f3c9a91ab6116bddd2865a49406 100644 (file)
@@ -45,6 +45,7 @@ SubtitleString::SubtitleString (
        optional<string> font,
        bool italic,
        bool bold,
+       bool underline,
        Colour colour,
        int size,
        float aspect_adjust,
@@ -64,6 +65,7 @@ SubtitleString::SubtitleString (
        : _font (font)
        , _italic (italic)
        , _bold (bold)
+       , _underline (underline)
        , _colour (colour)
        , _size (size)
        , _aspect_adjust (aspect_adjust)
@@ -101,6 +103,7 @@ dcp::operator== (SubtitleString const & a, SubtitleString const & b)
                a.font() == b.font() &&
                a.italic() == b.italic() &&
                a.bold() == b.bold() &&
+               a.underline() == b.underline() &&
                a.colour() == b.colour() &&
                a.size() == b.size() &&
                fabs (a.aspect_adjust() - b.aspect_adjust()) < ASPECT_ADJUST_EPSILON &&
@@ -138,6 +141,10 @@ dcp::operator<< (ostream& s, SubtitleString const & sub)
                s << "normal, ";
        }
 
+       if (sub.underline()) {
+               s << "underlined, ";
+       }
+
        s << "size " << sub.size() << ", aspect " << sub.aspect_adjust() << ", colour " << sub.colour()
          << ", vpos " << sub.v_position() << ", valign " << ((int) sub.v_align())
          << ", hpos " << sub.h_position() << ", halign " << ((int) sub.h_align())
index b16f764bb0ea6c285f07562a37338a3ee902d7af..51b3756439db695fa297046de16b75d6559b9c0f 100644 (file)
@@ -55,6 +55,7 @@ public:
                boost::optional<std::string> font,
                bool italic,
                bool bold,
+               bool underline,
                Colour colour,
                int size,
                float aspect_adjust,
@@ -85,6 +86,10 @@ public:
                return _bold;
        }
 
+       bool underline () const {
+               return _underline;
+       }
+
        Colour colour () const {
                return _colour;
        }
@@ -189,6 +194,8 @@ private:
        bool _italic;
        /** true if the weight is bold, false for normal */
        bool _bold;
+       /** true to enable underlining, false otherwise */
+       bool _underline;
        /** text colour */
        Colour _colour;
        /** Size in points as if the screen height is 11 inches, so a 72pt font
index f4a4ded810392e5563386a3a1c782976fd07cc8c..ee57db02835910ab31a5d8b719fc1fb8ef4faa3d 100644 (file)
@@ -20,7 +20,7 @@
     <Subtitle SpotNumber="3" TimeIn="00:00:11:094" TimeOut="00:00:13:063" FadeUpTime="1" FadeDownTime="1">
       <Text VAlign="bottom" VPosition="15.0">Once belonged to the Shah</Text>
     </Subtitle>
-    <Font Weight="bold">
+    <Font Weight="bold" Underlined="yes">
       <Subtitle SpotNumber="4" TimeIn="00:00:13:104" TimeOut="00:00:15:177" FadeUpTime="1" FadeDownTime="1">
        <Text VAlign="bottom" VPosition="15.0">And these are Roy Hattersley's jeans</Text>
       </Subtitle>
index 3ec70296768ba7aa6e3505d0bf1d29daa33b9a37..7febaab485696b617548d4ec2483354c1cb93f6e 100644 (file)
@@ -50,6 +50,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
                                   string ("theFontId"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   39,
                                   1.0,
@@ -73,6 +74,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
                                   string ("theFontId"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   39,
                                   1.0,
@@ -93,6 +95,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
                                   string ("theFontId"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   39,
                                   1.0,
@@ -116,6 +119,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
                                   string ("theFontId"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   39,
                                   1.0,
@@ -139,6 +143,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test1)
                                   string ("theFontId"),
                                   false,
                                   true,
+                                  true,
                                   dcp::Colour (255, 255, 255),
                                   39,
                                   1.0,
@@ -168,6 +173,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -188,6 +194,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -211,6 +218,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -231,6 +239,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -254,6 +263,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -274,6 +284,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -297,6 +308,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -317,6 +329,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -340,6 +353,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -360,6 +374,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -383,6 +398,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -403,6 +419,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -426,6 +443,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -446,6 +464,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -469,6 +488,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -489,6 +509,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   false,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -512,6 +533,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
@@ -532,6 +554,7 @@ BOOST_AUTO_TEST_CASE (read_interop_subtitle_test2)
                                   string ("theFont"),
                                   true,
                                   false,
+                                  false,
                                   dcp::Colour (255, 255, 255),
                                   42,
                                   1.0,
index 648d5928272d19a441081d9220c7e30bb77ff8e4..14d19d8b873b25d9103204e8463bdf89239e2c15 100644 (file)
@@ -40,6 +40,7 @@ BOOST_AUTO_TEST_CASE (write_interop_subtitle_test)
                        string ("Frutiger"),
                        false,
                        false,
+                       false,
                        dcp::Colour (255, 255, 255),
                        48,
                        1.0,
@@ -63,6 +64,7 @@ BOOST_AUTO_TEST_CASE (write_interop_subtitle_test)
                        boost::optional<string> (),
                        true,
                        true,
+                       true,
                        dcp::Colour (128, 0, 64),
                        91,
                        1.0,
@@ -95,7 +97,7 @@ BOOST_AUTO_TEST_CASE (write_interop_subtitle_test)
                "      <Text VAlign=\"top\" VPosition=\"80\">Hello world</Text>\n"
                "    </Subtitle>\n"
                "  </Font>\n"
-               "  <Font Italic=\"yes\" Color=\"FF800040\" Size=\"91\" Effect=\"border\" EffectColor=\"FF010203\" Script=\"normal\" Underlined=\"no\" Weight=\"bold\">\n"
+               "  <Font Italic=\"yes\" Color=\"FF800040\" Size=\"91\" Effect=\"border\" EffectColor=\"FF010203\" Script=\"normal\" Underlined=\"yes\" Weight=\"bold\">\n"
                "    <Subtitle SpotNumber=\"2\" TimeIn=\"05:41:00:218\" TimeOut=\"06:12:15:218\" FadeUpTime=\"930792\" FadeDownTime=\"4591834\">\n"
                "      <Text VAlign=\"bottom\" VPosition=\"40\">What's going on</Text>\n"
                "    </Subtitle>\n"
@@ -119,6 +121,7 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test)
                        string ("Frutiger"),
                        false,
                        false,
+                       false,
                        dcp::Colour (255, 255, 255),
                        48,
                        1.0,
@@ -142,6 +145,7 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test)
                        boost::optional<string> (),
                        true,
                        true,
+                       true,
                        dcp::Colour (128, 0, 64),
                        91,
                        1.0,
@@ -179,7 +183,7 @@ BOOST_AUTO_TEST_CASE (write_smpte_subtitle_test)
                "        <dcst:Text Valign=\"top\" Vposition=\"80\">Hello world</dcst:Text>\n"
                "      </dcst:Subtitle>\n"
                "    </dcst:Font>\n"
-               "    <dcst:Font Italic=\"yes\" Color=\"FF800040\" Size=\"91\" Effect=\"border\" EffectColor=\"FF010203\" Script=\"normal\" Underline=\"no\" Weight=\"bold\">\n"
+               "    <dcst:Font Italic=\"yes\" Color=\"FF800040\" Size=\"91\" Effect=\"border\" EffectColor=\"FF010203\" Script=\"normal\" Underline=\"yes\" Weight=\"bold\">\n"
                "      <dcst:Subtitle SpotNumber=\"2\" TimeIn=\"05:41:00:21\" TimeOut=\"06:12:15:21\" FadeUpTime=\"01:02:03:04\" FadeDownTime=\"05:06:07:08\">\n"
                "        <dcst:Text Valign=\"bottom\" Vposition=\"40\" Direction=\"rtl\">What's going on</dcst:Text>\n"
                "      </dcst:Subtitle>\n"