forked from mia/Aegisub
Extract duplicated ASS writing code from libass provider
This commit is contained in:
parent
b24e2c33e0
commit
31af9c575f
5 changed files with 34 additions and 37 deletions
|
@ -68,7 +68,7 @@ void AssSubtitleFormat::ReadFile(AssFile *target, agi::fs::path const& filename,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
std::string format(AssEntryGroup group, bool ssa) {
|
const char *format(AssEntryGroup group, bool ssa) {
|
||||||
if (group == AssEntryGroup::DIALOGUE) {
|
if (group == AssEntryGroup::DIALOGUE) {
|
||||||
if (ssa)
|
if (ssa)
|
||||||
return "Format: Marked, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text" LINEBREAK;
|
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 "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 {
|
struct Writer {
|
||||||
TextFileWriter file;
|
TextFileWriter file;
|
||||||
bool ssa;
|
bool ssa = false;
|
||||||
AssEntryGroup group = AssEntryGroup::INFO;
|
AssEntryGroup group = AssEntryGroup::INFO;
|
||||||
|
|
||||||
|
Writer(std::ostream &ostr) : file(ostr) {
|
||||||
|
file.WriteLineToFile("[Script Info]");
|
||||||
|
}
|
||||||
|
|
||||||
Writer(agi::fs::path const& filename, std::string const& encoding)
|
Writer(agi::fs::path const& filename, std::string const& encoding)
|
||||||
: file(filename, encoding)
|
: file(filename, encoding)
|
||||||
, ssa(agi::fs::HasExtension(filename, "ssa"))
|
, ssa(agi::fs::HasExtension(filename, "ssa"))
|
||||||
|
@ -108,7 +112,8 @@ struct Writer {
|
||||||
file.WriteLineToFile("");
|
file.WriteLineToFile("");
|
||||||
|
|
||||||
file.WriteLineToFile(line.GroupHeader(ssa));
|
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();
|
group = line.Group();
|
||||||
}
|
}
|
||||||
|
@ -135,9 +140,7 @@ struct Writer {
|
||||||
// the inline_string encoding grew the data by more than uuencoding would
|
// the inline_string encoding grew the data by more than uuencoding would
|
||||||
// so base64 encode it instead
|
// so base64 encode it instead
|
||||||
line += "u"; // marker for uuencoding
|
line += "u"; // marker for uuencoding
|
||||||
encoded_data = agi::ass::UUEncode(edi.second.second, false);
|
line += 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;
|
|
||||||
} else {
|
} else {
|
||||||
line += "e"; // marker for inline_string encoding (escaping)
|
line += "e"; // marker for inline_string encoding (escaping)
|
||||||
line += encoded_data;
|
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 {
|
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 writer(filename, encoding);
|
||||||
|
|
||||||
writer.Write(src->Info);
|
writer.Write(src->Info);
|
||||||
writer.Write(src->Styles);
|
writer.Write(src->Styles);
|
||||||
writer.Write(src->Attachments);
|
writer.Write(src->Attachments);
|
||||||
writer.Write(src->Events);
|
writer.Write(src->Events);
|
||||||
writer.WriteExtradata(src->Extradata);
|
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 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;
|
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 "ass_style.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "include/aegisub/subtitles_provider.h"
|
#include "include/aegisub/subtitles_provider.h"
|
||||||
|
#include "subtitle_format_ass.h"
|
||||||
#include "video_frame.h"
|
#include "video_frame.h"
|
||||||
|
|
||||||
#include <libaegisub/background_runner.h>
|
#include <libaegisub/background_runner.h>
|
||||||
|
@ -50,6 +51,7 @@
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <boost/gil/gil_all.hpp>
|
#include <boost/gil/gil_all.hpp>
|
||||||
|
#include <boost/interprocess/streams/vectorstream.hpp>
|
||||||
#include <boost/range/algorithm_ext/push_back.hpp>
|
#include <boost/range/algorithm_ext/push_back.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
@ -153,33 +155,13 @@ LibassSubtitlesProvider::~LibassSubtitlesProvider() {
|
||||||
if (ass_track) ass_free_track(ass_track);
|
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) {
|
void LibassSubtitlesProvider::LoadSubtitles(AssFile *subs) {
|
||||||
Writer writer;
|
boost::interprocess::basic_ovectorstream<std::vector<char>> ostr;
|
||||||
|
ostr.reserve(0x4000);
|
||||||
writer.data.reserve(0x4000);
|
AssSubtitleFormat::WriteToStream(subs, ostr);
|
||||||
|
|
||||||
writer.Write(subs->Info);
|
|
||||||
writer.Write(subs->Styles);
|
|
||||||
writer.Write(subs->Events);
|
|
||||||
|
|
||||||
if (ass_track) ass_free_track(ass_track);
|
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.";
|
if (!ass_track) throw "libass failed to load subtitles.";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
|
|
||||||
TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding)
|
TextFileWriter::TextFileWriter(agi::fs::path const& filename, std::string encoding)
|
||||||
: file(new agi::io::Save(filename, true))
|
: file(new agi::io::Save(filename, true))
|
||||||
, conv()
|
, ostr(file->Get())
|
||||||
{
|
{
|
||||||
if (encoding.empty())
|
if (encoding.empty())
|
||||||
encoding = OPT_GET("App/Save Charset")->GetString();
|
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() {
|
TextFileWriter::~TextFileWriter() {
|
||||||
// Explicit empty destructor required with a unique_ptr to an incomplete class
|
// 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)
|
if (addLineBreak)
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
line += "\r\n";
|
line += "\r\n";
|
||||||
|
@ -62,5 +66,5 @@ void TextFileWriter::WriteLineToFile(std::string&& line, bool addLineBreak) {
|
||||||
|
|
||||||
if (conv)
|
if (conv)
|
||||||
line = conv->Convert(line);
|
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 {
|
class TextFileWriter {
|
||||||
std::unique_ptr<agi::io::Save> file;
|
std::unique_ptr<agi::io::Save> file;
|
||||||
std::unique_ptr<agi::charset::IconvWrapper> conv;
|
std::unique_ptr<agi::charset::IconvWrapper> conv;
|
||||||
|
std::ostream &ostr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TextFileWriter(agi::fs::path const& filename, std::string encoding="");
|
TextFileWriter(agi::fs::path const& filename, std::string encoding="");
|
||||||
|
TextFileWriter(std::ostream &ostr);
|
||||||
~TextFileWriter();
|
~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 a new issue