/* Copyright (C) 2012-2020 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 the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "util.h" #include "reader.h" #include "subtitle.h" #include "collect.h" #include #include #include #include #include using std::string; using std::getline; using std::ostream; using std::map; using std::shared_ptr; using std::vector; using boost::optional; using namespace sub; /** @param s A string. * @return true if the string contains only space, newline or tab characters, or is empty. */ bool sub::empty_or_white_space (string s) { for (size_t i = 0; i < s.length(); ++i) { if (s[i] != ' ' && s[i] != '\n' && s[i] != '\t') { return false; } } return true; } optional sub::get_line_string (string* s) { if (s->length() == 0) { return optional(); } size_t pos = s->find ("\n"); if (pos == string::npos) { string const c = *s; *s = ""; return c; } string const c = s->substr (0, pos); s->erase (0, pos + 1); return c; } optional sub::get_line_file (FILE* f) { char buffer[256]; char* r = fgets (buffer, sizeof (buffer), f); if (r == 0) { return optional (); } return string (buffer); } void sub::remove_unicode_bom (optional& line) { if ( line->length() >= 3 && static_cast (line.get()[0]) == 0xef && static_cast (line.get()[1]) == 0xbb && static_cast (line.get()[2]) == 0xbf ) { /* Skip Unicode byte order mark */ line = line->substr (3); } } void sub::dump (shared_ptr reader, ostream& os) { auto metadata = reader->metadata (); for (auto const& i: metadata) { os << i.first << ": " << i.second << "\n"; } auto subs = collect> (reader->subtitles()); int n = 0; for (auto const& i: subs) { os << "Subtitle " << n << " at " << i.from << " -> " << i.to << "\n"; for (auto const& j: i.lines) { os << "\t"; if (j.vertical_position.proportional) { os << j.vertical_position.proportional.get() << " of screen"; } else if (j.vertical_position.line && j.vertical_position.lines) { os << j.vertical_position.line.get() << " lines of " << j.vertical_position.lines.get(); } if (j.vertical_position.reference) { os << " from "; switch (j.vertical_position.reference.get()) { case TOP_OF_SCREEN: os << "top"; break; case VERTICAL_CENTRE_OF_SCREEN: os << "centre"; break; case BOTTOM_OF_SCREEN: os << "bottom"; break; case TOP_OF_SUBTITLE: os << "top of subtitle"; break; } } os << "\t"; bool italic = false; bool underline = false; for (auto const& k: j.blocks) { if (k.italic && !italic) { os << ""; } else if (italic && !k.italic) { os << ""; } if (k.underline && !underline) { os << ""; } else if (underline && !k.underline) { os << ""; } italic = k.italic; underline = k.underline; os << k.text; } if (italic) { os << ""; } if (underline) { os << ""; } os << "\n"; } ++n; } }