X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fsubrip_reader.cc;h=e5f113da1d294c17d31792ccbd79b103dc9b742f;hb=0a1b4c69c23d6e4838707fe74f3a55aa7b6c8649;hp=644a23cf877eff168b699fd378448e16a3ffb1d8;hpb=d704110228aae2bc7cd2ebc8ccd23d78be4fef9b;p=libsub.git diff --git a/src/subrip_reader.cc b/src/subrip_reader.cc index 644a23c..e5f113d 100644 --- a/src/subrip_reader.cc +++ b/src/subrip_reader.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2014 Carl Hetherington + Copyright (C) 2014-2015 Carl Hetherington This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -17,24 +17,48 @@ */ +/** @file src/subrip_reader.cc + * @brief SubripReader class. + */ + #include "subrip_reader.h" #include "exceptions.h" +#include "util.h" #include #include #include +#include #include #include +#include using std::string; using std::vector; using std::list; using std::cout; using std::hex; +using std::stringstream; using boost::lexical_cast; using boost::to_upper; +using boost::optional; +using boost::function; using namespace sub; +/** @param s Subtitle string encoded in UTF-8 */ +SubripReader::SubripReader (string const & s) +{ + stringstream str (s); + this->read (boost::bind (&get_line_stringstream, &str)); +} + +/** @param f Subtitle file encoded in UTF-8 */ SubripReader::SubripReader (FILE* f) +{ + this->read (boost::bind (&get_line_file, f)); +} + +void +SubripReader::read (function ()> get_line) { enum { COUNTER, @@ -42,55 +66,54 @@ SubripReader::SubripReader (FILE* f) CONTENT } state = COUNTER; - char buffer[256]; - - Time from; - Time to; + RawSubtitle rs; - string line; - int line_number = 0; + /* This reader extracts no information about where the subtitle + should be on screen, so its reference is TOP_OF_SUBTITLE. + */ + rs.vertical_position.line = 0; + rs.vertical_position.reference = TOP_OF_SUBTITLE; - while (!feof (f)) { - char* r = fgets (buffer, sizeof (buffer), f); - if (r == 0 || feof (f)) { + while (true) { + optional line = get_line (); + if (!line) { break; } - line = string (buffer); - trim_right_if (line, boost::is_any_of ("\n\r")); - - if ( - line.length() >= 3 && - static_cast (line[0]) == 0xef && - static_cast (line[1]) == 0xbb && - static_cast (line[2]) == 0xbf - ) { - - /* Skip Unicode byte order mark */ - line = line.substr (3); - } + trim_right_if (*line, boost::is_any_of ("\n\r")); + remove_unicode_bom (line); switch (state) { case COUNTER: { - if (line.empty ()) { + if (line->empty ()) { /* a blank line at the start is ok */ break; } state = METADATA; + + /* Reset stuff that should not persist across separate subtitles */ + rs.bold = false; + rs.italic = false; + rs.underline = false; + rs.vertical_position.line = 0; } break; case METADATA: { vector p; - boost::algorithm::split (p, line, boost::algorithm::is_any_of (" ")); + + /* Further trim this line, removing spaces from the end */ + trim_right_if (*line, boost::is_any_of (" ")); + + boost::algorithm::split (p, *line, boost::algorithm::is_any_of (" ")); if (p.size() != 3 && p.size() != 7) { - throw SubripError (line, "a time/position line"); + throw SubripError (*line, "a time/position line"); } - from = convert_time (p[0]); - to = convert_time (p[2]); + rs.from = convert_time (p[0]); + rs.to = convert_time (p[2]); /* XXX: should not ignore coordinate specifications */ @@ -98,12 +121,11 @@ SubripReader::SubripReader (FILE* f) break; } case CONTENT: - if (line.empty ()) { + if (line->empty ()) { state = COUNTER; - line_number = 0; } else { - convert_line (line, line_number, from, to); - line_number++; + convert_line (*line, rs); + rs.vertical_position.line = rs.vertical_position.line.get() + 1; } break; } @@ -131,7 +153,7 @@ SubripReader::convert_time (string t) } void -SubripReader::convert_line (string t, int line_number, Time from, Time to) +SubripReader::convert_line (string t, RawSubtitle& p) { enum { TEXT, @@ -140,16 +162,6 @@ SubripReader::convert_line (string t, int line_number, Time from, Time to) string tag; - RawSubtitle p; - p.font = "Arial"; - p.font_size.set_points (48); - p.from = from; - p.to = to; - p.vertical_position.line = line_number; - /* XXX: arbitrary */ - p.vertical_position.lines = 32; - p.vertical_position.reference = TOP_OF_SUBTITLE; - list colours; colours.push_back (Colour (1, 1, 1)); @@ -212,6 +224,7 @@ SubripReader::convert_line (string t, int line_number, Time from, Time to) maybe_content (p); } +/* Push p into _subs if it has some text, and clear the text out of p */ void SubripReader::maybe_content (RawSubtitle& p) {