X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fssa_reader.cc;h=c76a78db34d006c4244e40f4d8e7423edfd5fc14;hb=70bd2d59775cf0e3d3bacac03bf07e6101860d5f;hp=f3180a7457993e46660e09b4ca9d82c2af830163;hpb=7114a99bf210c5d41a13161aea868fe68dd06e84;p=libsub.git diff --git a/src/ssa_reader.cc b/src/ssa_reader.cc index f3180a7..c76a78d 100644 --- a/src/ssa_reader.cc +++ b/src/ssa_reader.cc @@ -26,6 +26,7 @@ #include #include #include +#include #include using std::string; @@ -33,6 +34,7 @@ using std::stringstream; using std::vector; using std::map; using std::cout; +using std::list; using boost::optional; using boost::function; using namespace boost::algorithm; @@ -136,6 +138,75 @@ SSAReader::parse_time (string t) const ); } +/** @param base RawSubtitle filled in with any required common values. + * @param line SSA line string. + * @return List of RawSubtitles to represent line with vertical reference TOP_OF_SUBTITLE. + */ +list +SSAReader::parse_line (RawSubtitle base, string line) +{ + enum { + TEXT, + STYLE, + BACKSLASH + } state = TEXT; + + list subs; + RawSubtitle current = base; + string style; + + current.vertical_position.line = 0; + /* XXX: arbitrary */ + current.vertical_position.lines = 32; + current.vertical_position.reference = TOP_OF_SUBTITLE; + + for (size_t i = 0; i < line.length(); ++i) { + char const c = line[i]; + switch (state) { + case TEXT: + if (c == '{') { + state = STYLE; + } else if (c == '\\') { + state = BACKSLASH; + } else if (c != '\r' && c != '\n') { + current.text += c; + } + break; + case STYLE: + if (c == '}') { + if (!current.text.empty ()) { + subs.push_back (current); + current.text = ""; + } + if (style == "i1") { + current.italic = true; + } else if (style == "i0") { + current.italic = false; + } + style = ""; + state = TEXT; + } else { + style += c; + } + break; + case BACKSLASH: + if ((c == 'n' || c == 'N') && !current.text.empty ()) { + subs.push_back (current); + current.text = ""; + current.vertical_position.line = current.vertical_position.line.get() + 1; + } + state = TEXT; + break; + } + } + + if (!current.text.empty ()) { + subs.push_back (current); + } + + return subs; +} + void SSAReader::read (function ()> get_line) { @@ -156,6 +227,7 @@ SSAReader::read (function ()> get_line) } trim (*line); + remove_unicode_bom (line); if (starts_with (*line, ";") || line->empty ()) { continue; @@ -202,6 +274,15 @@ SSAReader::read (function ()> get_line) vector event; split (event, body, is_any_of (",")); + /* There may be commas in the subtitle part; reassemble any extra parts + from when we just split it. + */ + while (event.size() > event_format.size()) { + string const ex = event.back (); + event.pop_back (); + event.back() += "," + ex; + } + SUB_ASSERT (!event.empty()); SUB_ASSERT (event_format.size() == event.size()); @@ -223,12 +304,18 @@ SSAReader::read (function ()> get_line) sub.bold = style.bold; sub.italic = style.italic; sub.effect = style.effect; + + /* XXX: arbitrary */ + sub.vertical_position.lines = 32; + sub.vertical_position.reference = TOP_OF_SUBTITLE; + sub.vertical_position.line = 0; + } else if (event_format[i] == "Text") { - sub.text = event[i]; + BOOST_FOREACH (sub::RawSubtitle j, parse_line (sub, event[i])) { + _subs.push_back (j); + } } } - - _subs.push_back (sub); } }