mirror of https://github.com/odrling/Aegisub
Extract duplicated ASS writing code from libass provider
This commit is contained in:
parent
b24e2c33e0
commit
31af9c575f
|
@ -68,7 +68,7 @@ void AssSubtitleFormat::ReadFile(AssFile *target, agi::fs::path const& filename,
|
|||
#endif
|
||||
|
||||
namespace {
|
||||
std::string format(AssEntryGroup group, bool ssa) {
|
||||
const char *format(AssEntryGroup group, bool ssa) {
|
||||
if (group == AssEntryGroup::DIALOGUE) {
|
||||
if (ssa)
|
||||
return "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" LINEBREAK;
|
||||
|
@ -83,14 +83,18 @@ std::string format(AssEntryGroup group, bool ssa) {
|
|||
return "Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding" LINEBREAK;
|
||||
}
|
||||
|
||||
return "";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct Writer {
|
||||
TextFileWriter file;
|
||||
bool ssa;
|
||||
bool ssa = false;
|
||||
AssEntryGroup group = AssEntryGroup::INFO;
|
||||
|
||||
Writer(std::ostream &ostr) : file(ostr) {
|
||||
file.WriteLineToFile("[Script Info]");
|
||||
}
|
||||
|
||||
Writer(agi::fs::path const& filename, std::string const& encoding)
|
||||
: file(filename, encoding)
|
||||
, ssa(agi::fs::HasExtension(filename, "ssa"))
|
||||
|
@ -108,7 +112,8 @@ struct Writer {
|
|||
file.WriteLineToFile("");
|
||||
|
||||
file.WriteLineToFile(line.GroupHeader(ssa));
|
||||
file.WriteLineToFile(format(line.Group(), ssa), false);
|
||||
if (const char *str = format(line.Group(), ssa))
|
||||
file.WriteLineToFile(str, false);
|
||||
|
||||
group = line.Group();
|
||||
}
|
||||
|
@ -135,9 +140,7 @@ struct Writer {
|
|||
// the inline_string encoding grew the data by more than uuencoding would
|
||||
// so base64 encode it instead
|
||||
line += "u"; // marker for uuencoding
|
||||
encoded_data = agi::ass::UUEncode(edi.second.second, false);
|
||||
printf("did uuencoding, original size=%lu, encoded size=%lu\n", edi.second.second.size(), encoded_data.size());
|
||||
line += encoded_data;
|
||||
line += agi::ass::UUEncode(edi.second.second, false);
|
||||
} else {
|
||||
line += "e"; // marker for inline_string encoding (escaping)
|
||||
line += encoded_data;
|
||||
|
@ -150,10 +153,16 @@ struct Writer {
|
|||
|
||||
void AssSubtitleFormat::WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const {
|
||||
Writer writer(filename, encoding);
|
||||
|
||||
writer.Write(src->Info);
|
||||
writer.Write(src->Styles);
|
||||
writer.Write(src->Attachments);
|
||||
writer.Write(src->Events);
|
||||
writer.WriteExtradata(src->Extradata);
|
||||
}
|
||||
|
||||
void AssSubtitleFormat::WriteToStream(const AssFile *src, std::ostream &ostr) {
|
||||
Writer writer(ostr);
|
||||
writer.Write(src->Info);
|
||||
writer.Write(src->Styles);
|
||||
writer.Write(src->Events);
|
||||
}
|
||||
|
|
|
@ -46,4 +46,5 @@ public:
|
|||
|
||||
void ReadFile(AssFile *target, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& forceEncoding) const override;
|
||||
void WriteFile(const AssFile *src, agi::fs::path const& filename, agi::vfr::Framerate const& fps, std::string const& encoding) const override;
|
||||
static void WriteToStream(const AssFile *src, std::ostream &ostr);
|
||||
};
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "ass_style.h"
|
||||
#include "compat.h"
|
||||
#include "include/aegisub/subtitles_provider.h"
|
||||
#include "subtitle_format_ass.h"
|
||||
#include "video_frame.h"
|
||||
|
||||
#include <libaegisub/background_runner.h>
|
||||
|
@ -50,6 +51,7 @@
|
|||
|
||||
#include <atomic>
|
||||
#include <boost/gil/gil_all.hpp>
|
||||
#include <boost/interprocess/streams/vectorstream.hpp>
|
||||
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
@ -153,33 +155,13 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() {
|
|||
if (ass_track) ass_free_track(ass_track);
|
||||
}
|
||||
|
||||
struct Writer {
|
||||
std::vector<char> data;
|
||||
AssEntryGroup group = AssEntryGroup::GROUP_MAX;
|
||||
|
||||
template<typename T>
|
||||
void Write(T const& list) {
|
||||
for (auto const& line : list) {
|
||||
if (group != line.Group()) {
|
||||
group = line.Group();
|
||||
boost::push_back(data, line.GroupHeader() + "\r\n");
|
||||
}
|
||||
boost::push_back(data, line.GetEntryData() + "\r\n");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs) {
|
||||
Writer writer;
|
||||
|
||||
writer.data.reserve(0x4000);
|
||||
|
||||
writer.Write(subs->Info);
|
||||
writer.Write(subs->Styles);
|
||||
writer.Write(subs->Events);
|
||||
boost::interprocess::basic_ovectorstream<std::vector<char>> ostr;
|
||||
ostr.reserve(0x4000);
|
||||
AssSubtitleFormat::WriteToStream(subs, ostr);
|
||||
|
||||
if (ass_track) ass_free_track(ass_track);
|
||||
ass_track = ass_read_memory(library, &writer.data[0], writer.data.size(), nullptr);
|
||||
ass_track = ass_read_memory(library, const_cast<char *>(ostr.vector().data()), ostr.vector().size(), nullptr);
|
||||
if (!ass_track) throw "libass failed to load subtitles.";
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding)
|
||||
: file(new agi::io::Save(filename, true))
|
||||
, conv()
|
||||
, ostr(file->Get())
|
||||
{
|
||||
if (encoding.empty())
|
||||
encoding = OPT_GET("App/Save Charset")->GetString();
|
||||
|
@ -48,11 +48,15 @@ TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encodi
|
|||
}
|
||||
}
|
||||
|
||||
TextFileWriter::TextFileWriter(std::ostream &ostr) : ostr(ostr) {
|
||||
WriteLineToFile("\xEF\xBB\xBF", false);
|
||||
}
|
||||
|
||||
TextFileWriter::~TextFileWriter() {
|
||||
// Explicit empty destructor required with a unique_ptr to an incomplete class
|
||||
}
|
||||
|
||||
void TextFileWriter::WriteLineToFile(std::string&& line, bool addLineBreak) {
|
||||
void TextFileWriter::WriteLineToFile(std::string line, bool addLineBreak) {
|
||||
if (addLineBreak)
|
||||
#ifdef _WIN32
|
||||
line += "\r\n";
|
||||
|
@ -62,5 +66,5 @@ void TextFileWriter::WriteLineToFile(std::string&& line, bool addLineBreak) {
|
|||
|
||||
if (conv)
|
||||
line = conv->Convert(line);
|
||||
file->Get().write(line.data(), line.size());
|
||||
ostr.write(line.data(), line.size());
|
||||
}
|
||||
|
|
|
@ -32,11 +32,12 @@ namespace agi {
|
|||
class TextFileWriter {
|
||||
std::unique_ptr<agi::io::Save> file;
|
||||
std::unique_ptr<agi::charset::IconvWrapper> conv;
|
||||
std::ostream &ostr;
|
||||
|
||||
public:
|
||||
TextFileWriter(agi::fs::path const& filename, std::string encoding="");
|
||||
TextFileWriter(std::ostream &ostr);
|
||||
~TextFileWriter();
|
||||
|
||||
void WriteLineToFile(std::string const& line, bool addLineBreak=true) { WriteLineToFile(std::string(line), addLineBreak); }
|
||||
void WriteLineToFile(std::string&& line, bool addLineBreak=true);
|
||||
void WriteLineToFile(std::string line, bool addLineBreak=true);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue