Auto3 engine for auto4 seems to work now
Originally committed to SVN as r833.
This commit is contained in:
parent
518c50d07d
commit
a2c8d7922e
29 changed files with 1639 additions and 122 deletions
File diff suppressed because it is too large
Load diff
|
@ -45,6 +45,10 @@
|
||||||
#include <wx/event.h>
|
#include <wx/event.h>
|
||||||
#include "../lua51/src/lua.h"
|
#include "../lua51/src/lua.h"
|
||||||
#include "../lua51/src/lauxlib.h"
|
#include "../lua51/src/lauxlib.h"
|
||||||
|
#include "ass_file.h"
|
||||||
|
#include "ass_entry.h"
|
||||||
|
#include "ass_dialogue.h"
|
||||||
|
#include "ass_style.h"
|
||||||
|
|
||||||
namespace Automation4 {
|
namespace Automation4 {
|
||||||
|
|
||||||
|
@ -64,40 +68,94 @@ namespace Automation4 {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum Auto3ScriptConfigurationOptionKind {
|
||||||
|
COK_INVALID = 0,
|
||||||
|
COK_LABEL,
|
||||||
|
COK_TEXT,
|
||||||
|
COK_INT,
|
||||||
|
COK_FLOAT,
|
||||||
|
COK_BOOL,
|
||||||
|
COK_COLOUR,
|
||||||
|
COK_STYLE
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Auto3ScriptConfigurationOption {
|
||||||
|
wxString name;
|
||||||
|
Auto3ScriptConfigurationOptionKind kind;
|
||||||
|
wxString label;
|
||||||
|
wxString hint;
|
||||||
|
union {
|
||||||
|
bool isset;
|
||||||
|
int intval;
|
||||||
|
double floatval;
|
||||||
|
} min, max;
|
||||||
|
struct {
|
||||||
|
wxString stringval;
|
||||||
|
int intval;
|
||||||
|
double floatval;
|
||||||
|
bool boolval;
|
||||||
|
AssColor colourval;
|
||||||
|
} default_val, value;
|
||||||
|
};
|
||||||
|
|
||||||
class Auto3ConfigDialog : public ScriptConfigDialog {
|
class Auto3ConfigDialog : public ScriptConfigDialog {
|
||||||
// copypasta
|
// copypasta
|
||||||
|
private:
|
||||||
|
bool present; // is there any configuration option set at all?
|
||||||
|
|
||||||
|
std::vector<Auto3ScriptConfigurationOption> options;
|
||||||
|
|
||||||
|
struct Control {
|
||||||
|
wxStaticText *label;
|
||||||
|
wxControl *control;
|
||||||
|
Auto3ScriptConfigurationOption *option;
|
||||||
|
Control() : label(0), control(0), option(0) {}
|
||||||
|
};
|
||||||
|
std::vector<Control> controls;
|
||||||
|
|
||||||
|
wxString ident;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
wxWindow* CreateWindow(wxWindow *parent);
|
wxWindow* CreateWindow(wxWindow *parent);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Auto3ConfigDialog(lua_State *_L, bool include_buttons);
|
Auto3ConfigDialog(lua_State *L, const wxString &_ident);
|
||||||
virtual ~Auto3ConfigDialog();
|
virtual ~Auto3ConfigDialog();
|
||||||
int LuaReadBack(lua_State *L); // read back internal structure to lua structures
|
int LuaReadBack(lua_State *L); // read back internal structure to lua structures
|
||||||
|
|
||||||
void ReadBack(); // from auto4 base
|
void ReadBack(); // from auto4 base
|
||||||
|
|
||||||
|
wxString serialize(); // make a string from the option name+value pairs
|
||||||
|
void unserialize(wxString &settings); // set the option values from a serialized string
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Auto3Filter : public FeatureFilter {
|
class Auto3Filter : public FeatureFilter {
|
||||||
protected:
|
private:
|
||||||
Auto3Filter(const wxString &_name, const wxString &_description, lua_State *_L);
|
Auto3ConfigDialog *config;
|
||||||
|
AssFile *_file;
|
||||||
|
lua_State *L;
|
||||||
|
|
||||||
|
protected:
|
||||||
ScriptConfigDialog* GenerateConfigDialog(wxWindow *parent);
|
ScriptConfigDialog* GenerateConfigDialog(wxWindow *parent);
|
||||||
|
|
||||||
void Init();
|
void Init();
|
||||||
public:
|
public:
|
||||||
|
Auto3Filter(const wxString &_name, const wxString &_description, lua_State *_L);
|
||||||
|
|
||||||
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
void ProcessSubs(AssFile *subs, wxWindow *export_dialog);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
class Auto3ThreadedCall : public wxThread {
|
class Auto3ThreadedProcessor : public wxThread {
|
||||||
// This is pretty much copy-paste from the non-legacy version
|
|
||||||
private:
|
private:
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
int nargs;
|
AssFile *file;
|
||||||
int nresults;
|
Auto3ConfigDialog *config;
|
||||||
|
Auto3ProgressSink *sink;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Auto3ThreadedCall(lua_State *_L, int _nargs, int _nresults);
|
Auto3ThreadedProcessor(lua_State *_L, AssFile *_file, Auto3ConfigDialog *_config, Auto3ProgressSink *_sink);
|
||||||
virtual ExitCode Entry();
|
virtual ExitCode Entry();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -107,9 +165,17 @@ namespace Automation4 {
|
||||||
Auto3Filter *filter;
|
Auto3Filter *filter;
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
|
|
||||||
|
static int LuaTextExtents(lua_State *L);
|
||||||
|
static int LuaInclude(lua_State *L);
|
||||||
|
static int LuaColorstringToRGB(lua_State *L);
|
||||||
|
static int LuaFrameFromMs(lua_State *L);
|
||||||
|
static int LuaMsFromFrame(lua_State *L);
|
||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
|
static Auto3Script* GetScriptObject(lua_State *L);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Auto3Script(const wxString &filename);
|
Auto3Script(const wxString &filename);
|
||||||
virtual ~Auto3Script();
|
virtual ~Auto3Script();
|
||||||
|
|
|
@ -97,74 +97,68 @@ namespace Automation4 {
|
||||||
|
|
||||||
|
|
||||||
// LuaScriptReader
|
// LuaScriptReader
|
||||||
struct LuaScriptReader {
|
LuaScriptReader::LuaScriptReader(const wxString &filename)
|
||||||
FILE *f;
|
{
|
||||||
bool first;
|
|
||||||
char *databuf;
|
|
||||||
static const size_t bufsize = 512;
|
|
||||||
LuaScriptReader(const wxString &filename)
|
|
||||||
{
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
f = _tfopen(filename.c_str(), _T("rb"));
|
f = _tfopen(filename.c_str(), _T("rb"));
|
||||||
#else
|
#else
|
||||||
f = fopen(filename.fn_str(), "rb");
|
f = fopen(filename.fn_str(), "rb");
|
||||||
#endif
|
#endif
|
||||||
first = true;
|
first = true;
|
||||||
databuf = new char[bufsize];
|
databuf = new char[bufsize];
|
||||||
}
|
}
|
||||||
~LuaScriptReader()
|
LuaScriptReader::~LuaScriptReader()
|
||||||
{
|
{
|
||||||
if (databuf)
|
if (databuf)
|
||||||
delete databuf;
|
delete databuf;
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LuaScriptReader::reader_func(lua_State *L, void *data, size_t *size)
|
||||||
|
{
|
||||||
|
LuaScriptReader *self = (LuaScriptReader*)(data);
|
||||||
|
unsigned char *b = (unsigned char *)self->databuf;
|
||||||
|
FILE *f = self->f;
|
||||||
|
|
||||||
|
if (feof(f)) {
|
||||||
|
*size = 0;
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char* reader_func(lua_State *L, void *data, size_t *size)
|
if (self->first) {
|
||||||
{
|
// check if file is sensible and maybe skip bom
|
||||||
LuaScriptReader *self = (LuaScriptReader*)(data);
|
if ((*size = fread(b, 1, 4, f)) == 4) {
|
||||||
unsigned char *b = (unsigned char *)self->databuf;
|
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) {
|
||||||
FILE *f = self->f;
|
// got an utf8 file with bom
|
||||||
|
// nothing further to do, already skipped the bom
|
||||||
if (feof(f)) {
|
fseek(f, -1, SEEK_CUR);
|
||||||
*size = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self->first) {
|
|
||||||
// check if file is sensible and maybe skip bom
|
|
||||||
if ((*size = fread(b, 1, 4, f)) == 4) {
|
|
||||||
if (b[0] == 0xEF && b[1] == 0xBB && b[2] == 0xBF) {
|
|
||||||
// got an utf8 file with bom
|
|
||||||
// nothing further to do, already skipped the bom
|
|
||||||
fseek(f, -1, SEEK_CUR);
|
|
||||||
} else {
|
|
||||||
// oops, not utf8 with bom
|
|
||||||
// check if there is some other BOM in place and complain if there is...
|
|
||||||
if ((b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00) || // utf32be
|
|
||||||
(b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF) || // utf32le
|
|
||||||
(b[0] == 0xFF && b[1] == 0xFE) || // utf16be
|
|
||||||
(b[0] == 0xFE && b[1] == 0xFF) || // utf16le
|
|
||||||
(b[0] == 0x2B && b[1] == 0x2F && b[2] == 0x76) || // utf7
|
|
||||||
(b[0] == 0x00 && b[2] == 0x00) || // looks like utf16be
|
|
||||||
(b[1] == 0x00 && b[3] == 0x00)) { // looks like utf16le
|
|
||||||
throw _T("The script file uses an unsupported character set. Only UTF-8 is supported.");
|
|
||||||
}
|
|
||||||
// assume utf8 without bom, and rewind file
|
|
||||||
fseek(f, 0, SEEK_SET);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// hmm, rather short file this...
|
// oops, not utf8 with bom
|
||||||
// doesn't have a bom, assume it's just ascii/utf8 without bom
|
// check if there is some other BOM in place and complain if there is...
|
||||||
return self->databuf; // *size is already set
|
if ((b[0] == 0xFF && b[1] == 0xFE && b[2] == 0x00 && b[3] == 0x00) || // utf32be
|
||||||
|
(b[0] == 0x00 && b[1] == 0x00 && b[2] == 0xFE && b[3] == 0xFF) || // utf32le
|
||||||
|
(b[0] == 0xFF && b[1] == 0xFE) || // utf16be
|
||||||
|
(b[0] == 0xFE && b[1] == 0xFF) || // utf16le
|
||||||
|
(b[0] == 0x2B && b[1] == 0x2F && b[2] == 0x76) || // utf7
|
||||||
|
(b[0] == 0x00 && b[2] == 0x00) || // looks like utf16be
|
||||||
|
(b[1] == 0x00 && b[3] == 0x00)) { // looks like utf16le
|
||||||
|
throw _T("The script file uses an unsupported character set. Only UTF-8 is supported.");
|
||||||
|
}
|
||||||
|
// assume utf8 without bom, and rewind file
|
||||||
|
fseek(f, 0, SEEK_SET);
|
||||||
}
|
}
|
||||||
self->first = false;
|
} else {
|
||||||
|
// hmm, rather short file this...
|
||||||
|
// doesn't have a bom, assume it's just ascii/utf8 without bom
|
||||||
|
return self->databuf; // *size is already set
|
||||||
}
|
}
|
||||||
|
self->first = false;
|
||||||
*size = fread(b, 1, bufsize, f);
|
|
||||||
|
|
||||||
return self->databuf;
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
*size = fread(b, 1, bufsize, f);
|
||||||
|
|
||||||
|
return self->databuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// LuaScript
|
// LuaScript
|
||||||
|
@ -235,6 +229,9 @@ namespace Automation4 {
|
||||||
// aegisub.text_extents
|
// aegisub.text_extents
|
||||||
lua_pushcfunction(L, LuaTextExtents);
|
lua_pushcfunction(L, LuaTextExtents);
|
||||||
lua_setfield(L, -2, "text_extents");
|
lua_setfield(L, -2, "text_extents");
|
||||||
|
// aegisub.lua_automation_version
|
||||||
|
lua_pushinteger(L, 4);
|
||||||
|
lua_setfield(L, -2, "lua_automation_version");
|
||||||
// store aegisub table to globals
|
// store aegisub table to globals
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
_stackcheck.check(0);
|
_stackcheck.check(0);
|
||||||
|
@ -242,7 +239,6 @@ namespace Automation4 {
|
||||||
// load user script
|
// load user script
|
||||||
LuaScriptReader script_reader(GetFilename());
|
LuaScriptReader script_reader(GetFilename());
|
||||||
if (lua_load(L, script_reader.reader_func, &script_reader, GetFilename().mb_str(wxConvUTF8))) {
|
if (lua_load(L, script_reader.reader_func, &script_reader, GetFilename().mb_str(wxConvUTF8))) {
|
||||||
//if (luaL_loadfile(L, GetFilename().mb_str(wxConvUTF8))) {
|
|
||||||
wxString *err = new wxString(lua_tostring(L, -1), wxConvUTF8);
|
wxString *err = new wxString(lua_tostring(L, -1), wxConvUTF8);
|
||||||
err->Prepend(_T("An error occurred loading the Lua script file \"") + GetFilename() + _T("\":\n\n"));
|
err->Prepend(_T("An error occurred loading the Lua script file \"") + GetFilename() + _T("\":\n\n"));
|
||||||
throw err->c_str();
|
throw err->c_str();
|
||||||
|
@ -401,7 +397,6 @@ namespace Automation4 {
|
||||||
|
|
||||||
LuaScriptReader script_reader(fname.GetFullPath());
|
LuaScriptReader script_reader(fname.GetFullPath());
|
||||||
if (lua_load(L, script_reader.reader_func, &script_reader, s->GetFilename().mb_str(wxConvUTF8))) {
|
if (lua_load(L, script_reader.reader_func, &script_reader, s->GetFilename().mb_str(wxConvUTF8))) {
|
||||||
//if (luaL_loadfile(L, fname.GetFullPath().mb_str(wxConvUTF8))) {
|
|
||||||
lua_pushfstring(L, "An error occurred loading the Lua script file \"%s\":\n\n%s", fname.GetFullPath().mb_str(wxConvUTF8).data(), lua_tostring(L, -1));
|
lua_pushfstring(L, "An error occurred loading the Lua script file \"%s\":\n\n%s", fname.GetFullPath().mb_str(wxConvUTF8).data(), lua_tostring(L, -1));
|
||||||
lua_error(L);
|
lua_error(L);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -48,6 +48,17 @@ class wxWindow;
|
||||||
|
|
||||||
namespace Automation4 {
|
namespace Automation4 {
|
||||||
|
|
||||||
|
// Manage reading in a Lua script file
|
||||||
|
struct LuaScriptReader {
|
||||||
|
FILE *f;
|
||||||
|
bool first;
|
||||||
|
char *databuf;
|
||||||
|
static const size_t bufsize = 512;
|
||||||
|
LuaScriptReader(const wxString &filename);
|
||||||
|
~LuaScriptReader();
|
||||||
|
static const char* reader_func(lua_State *L, void *data, size_t *size);
|
||||||
|
};
|
||||||
|
|
||||||
// Provides access to an AssFile object (and all lines contained) for a Lua script
|
// Provides access to an AssFile object (and all lines contained) for a Lua script
|
||||||
class LuaAssFile {
|
class LuaAssFile {
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -95,13 +95,6 @@ void DialogAutomation::RebuildList()
|
||||||
list->DeleteAllItems();
|
list->DeleteAllItems();
|
||||||
|
|
||||||
// fill the list view
|
// fill the list view
|
||||||
const std::vector<Automation4::Script*> &global_scripts = global_manager->GetScripts();
|
|
||||||
for (std::vector<Automation4::Script*>::const_iterator i = global_scripts.begin(); i != global_scripts.end(); ++i) {
|
|
||||||
ExtraScriptInfo ei;
|
|
||||||
ei.script = *i;
|
|
||||||
ei.is_global = true;
|
|
||||||
AddScript(ei);
|
|
||||||
}
|
|
||||||
const std::vector<Automation4::Script*> &local_scripts = local_manager->GetScripts();
|
const std::vector<Automation4::Script*> &local_scripts = local_manager->GetScripts();
|
||||||
for (std::vector<Automation4::Script*>::const_iterator i = local_scripts.begin(); i != local_scripts.end(); ++i) {
|
for (std::vector<Automation4::Script*>::const_iterator i = local_scripts.begin(); i != local_scripts.end(); ++i) {
|
||||||
ExtraScriptInfo ei;
|
ExtraScriptInfo ei;
|
||||||
|
@ -109,6 +102,13 @@ void DialogAutomation::RebuildList()
|
||||||
ei.is_global = false;
|
ei.is_global = false;
|
||||||
AddScript(ei);
|
AddScript(ei);
|
||||||
}
|
}
|
||||||
|
const std::vector<Automation4::Script*> &global_scripts = global_manager->GetScripts();
|
||||||
|
for (std::vector<Automation4::Script*>::const_iterator i = global_scripts.begin(); i != global_scripts.end(); ++i) {
|
||||||
|
ExtraScriptInfo ei;
|
||||||
|
ei.script = *i;
|
||||||
|
ei.is_global = true;
|
||||||
|
AddScript(ei);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -168,19 +168,26 @@ END_EVENT_TABLE()
|
||||||
void DialogAutomation::OnAdd(wxCommandEvent &evt)
|
void DialogAutomation::OnAdd(wxCommandEvent &evt)
|
||||||
{
|
{
|
||||||
// build filename filter list
|
// build filename filter list
|
||||||
wxString fnfilter;
|
wxString fnfilter, catchall;
|
||||||
const std::vector<Automation4::ScriptFactory*> &factories = Automation4::ScriptFactory::GetFactories();
|
const std::vector<Automation4::ScriptFactory*> &factories = Automation4::ScriptFactory::GetFactories();
|
||||||
for (int i = 0; i < (int)factories.size(); i++) {
|
for (int i = 0; i < (int)factories.size(); i++) {
|
||||||
const Automation4::ScriptFactory *fact = factories[i];
|
const Automation4::ScriptFactory *fact = factories[i];
|
||||||
if (fact->GetEngineName().IsEmpty() || fact->GetFilenamePattern().IsEmpty())
|
if (fact->GetEngineName().IsEmpty() || fact->GetFilenamePattern().IsEmpty())
|
||||||
continue;
|
continue;
|
||||||
fnfilter = wxString::Format(_T("%s%s scripts|%s|"), fnfilter.c_str(), fact->GetEngineName().c_str(), fact->GetFilenamePattern().c_str());
|
fnfilter = wxString::Format(_T("%s%s scripts (%s)|%s|"), fnfilter.c_str(), fact->GetEngineName().c_str(), fact->GetFilenamePattern().c_str(), fact->GetFilenamePattern().c_str());
|
||||||
|
catchall << fact->GetFilenamePattern() << _T(";");
|
||||||
}
|
}
|
||||||
#ifdef __WINDOWS__
|
#ifdef __WINDOWS__
|
||||||
fnfilter += _T("All files|*.*");
|
fnfilter += _T("All files|*.*");
|
||||||
#else
|
#else
|
||||||
fnfilter += _T("All files|*");
|
fnfilter += _T("All files|*");
|
||||||
#endif
|
#endif
|
||||||
|
if (!catchall.IsEmpty()) {
|
||||||
|
catchall.RemoveLast();
|
||||||
|
}
|
||||||
|
if (factories.size() > 1) {
|
||||||
|
fnfilter = _T("All script formats|") + catchall + _T("|") + fnfilter;
|
||||||
|
}
|
||||||
|
|
||||||
wxString fname = wxFileSelector(_("Add Automation script"), Options.AsText(_T("Last open automation path")), wxEmptyString, wxEmptyString, fnfilter, wxOPEN|wxFILE_MUST_EXIST, this);
|
wxString fname = wxFileSelector(_("Add Automation script"), Options.AsText(_T("Last open automation path")), wxEmptyString, wxEmptyString, fnfilter, wxOPEN|wxFILE_MUST_EXIST, this);
|
||||||
|
|
||||||
|
|
150
aegisub/subtitle_provider_dtextsub.cpp
Normal file
150
aegisub/subtitle_provider_dtextsub.cpp
Normal file
|
@ -0,0 +1,150 @@
|
||||||
|
// Copyright (c) 2007, Niels Martin Hansen
|
||||||
|
// All rights reserved.
|
||||||
|
//
|
||||||
|
// Redistribution and use in source and binary forms, with or without
|
||||||
|
// modification, are permitted provided that the following conditions are met:
|
||||||
|
//
|
||||||
|
// * Redistributions of source code must retain the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer.
|
||||||
|
// * Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
// this list of conditions and the following disclaimer in the documentation
|
||||||
|
// and/or other materials provided with the distribution.
|
||||||
|
// * Neither the name of the Aegisub Group nor the names of its contributors
|
||||||
|
// may be used to endorse or promote products derived from this software
|
||||||
|
// without specific prior written permission.
|
||||||
|
//
|
||||||
|
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
// POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
//
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// AEGISUB
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:jiifurusu@gmail.com
|
||||||
|
//
|
||||||
|
|
||||||
|
// Use Gabest's RenderedTextSubtitles directly
|
||||||
|
|
||||||
|
#if USE_DTEXTSUB == 1
|
||||||
|
|
||||||
|
#include <wx/wxprec.h>
|
||||||
|
#include <wx/image.h>
|
||||||
|
#include "ass_file.h"
|
||||||
|
#include "subtitle_provider.h"
|
||||||
|
#include "video_provider.h"
|
||||||
|
#include <windows.h>
|
||||||
|
#include "vsfilter_editor_plugin.h"
|
||||||
|
|
||||||
|
#pragma comment(lib, "vsfilter.lib")
|
||||||
|
|
||||||
|
class SubtitleProviderDTextSub : public SubtitleProvider, public SubtitleProvider::Overlay {
|
||||||
|
private:
|
||||||
|
// A little copy-paste from the libass code...
|
||||||
|
class MyClass : public Class {
|
||||||
|
public:
|
||||||
|
MyClass() : Class(L"DirectTextSub")
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual SubtitleProvider *Get(AssFile *subs)
|
||||||
|
{
|
||||||
|
return new SubtitleProviderDTextSub(subs);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
static MyClass me;
|
||||||
|
|
||||||
|
EditorPluginRenderer *renderer;
|
||||||
|
RECT rect;
|
||||||
|
|
||||||
|
AssFile *subs;
|
||||||
|
VideoProvider *vpro;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SubtitleProviderDTextSub(AssFile *_subs);
|
||||||
|
virtual ~SubtitleProviderDTextSub();
|
||||||
|
virtual void Bind(VideoProvider *_vpro);
|
||||||
|
|
||||||
|
virtual void SetParams(int width, int height);
|
||||||
|
virtual void Render(wxImage &frame, int ms);
|
||||||
|
virtual void Unbind();
|
||||||
|
};
|
||||||
|
|
||||||
|
SubtitleProviderDTextSub::MyClass SubtitleProviderDTextSub::me;
|
||||||
|
|
||||||
|
|
||||||
|
SubtitleProviderDTextSub::SubtitleProviderDTextSub(AssFile *_subs)
|
||||||
|
: vpro(0)
|
||||||
|
{
|
||||||
|
subs = _subs;
|
||||||
|
renderer = renderer_new();
|
||||||
|
if (!renderer)
|
||||||
|
throw _T("Failed to create VSFilter Editor Interface renderer");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SubtitleProviderDTextSub::~SubtitleProviderDTextSub()
|
||||||
|
{
|
||||||
|
Unbind();
|
||||||
|
renderer_free(renderer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubtitleProviderDTextSub::Bind(VideoProvider *_vpro)
|
||||||
|
{
|
||||||
|
vpro = _vpro;
|
||||||
|
vpro->AttachOverlay(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubtitleProviderDTextSub::SetParams(int width, int height)
|
||||||
|
{
|
||||||
|
SIZE screen;
|
||||||
|
SIZE script;
|
||||||
|
screen.cx = width;
|
||||||
|
screen.cy = height;
|
||||||
|
if (subs) {
|
||||||
|
int w, h;
|
||||||
|
subs->GetResolution(w, h);
|
||||||
|
script.cx = w;
|
||||||
|
script.cy = h;
|
||||||
|
} else {
|
||||||
|
script.cx = width;
|
||||||
|
script.cy = height;
|
||||||
|
}
|
||||||
|
renderer_set_resolution(renderer, &script, &screen, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubtitleProviderDTextSub::Render(wxImage &frame, int ms)
|
||||||
|
{
|
||||||
|
// TODO: some way to discover whether it was just a seek and nothing needs to be reloaded
|
||||||
|
renderer_clear(renderer);
|
||||||
|
|
||||||
|
for (entryIter l = subs->Line.begin(); l != subs->Line.end(); ++l) {
|
||||||
|
}
|
||||||
|
|
||||||
|
BYTE *bits = frame.GetData();
|
||||||
|
|
||||||
|
renderer_render_overlay(renderer, ms, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SubtitleProviderDTextSub::Unbind()
|
||||||
|
{
|
||||||
|
if (vpro)
|
||||||
|
vpro->AttachOverlay(NULL);
|
||||||
|
vpro = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
81
aegisub/vsfilter_editor_plugin.h
Normal file
81
aegisub/vsfilter_editor_plugin.h
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2007 Niels Martin Hansen
|
||||||
|
* http://www.aegisub.net/
|
||||||
|
*
|
||||||
|
* 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, 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 GNU Make; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
* http://www.gnu.org/copyleft/gpl.html
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// This file provides a renderer-interface suited for applications
|
||||||
|
// that need to interactively update the subtitles and re-render
|
||||||
|
// the frame often, with modified subs.
|
||||||
|
|
||||||
|
|
||||||
|
// Don't include windows.h if this is an MFC project (it won't compile)
|
||||||
|
#ifndef __AFX_H__
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef PLUGIN_INTERFACE
|
||||||
|
#define _i_defined_plugin_interface
|
||||||
|
#define PLUGIN_INTERFACE extern "C" __declspec(dllimport)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
struct EditorPluginRenderer;
|
||||||
|
|
||||||
|
|
||||||
|
// Create a new renderer and return an opaque handle to it
|
||||||
|
// Returns NULL on fail
|
||||||
|
PLUGIN_INTERFACE EditorPluginRenderer *renderer_new();
|
||||||
|
// Free a renderer object
|
||||||
|
// Does not fail
|
||||||
|
PLUGIN_INTERFACE void renderer_free(EditorPluginRenderer *renderer);
|
||||||
|
// Set renderer resolution and clear all styles+dialogue data
|
||||||
|
// renderer and script_res are mandatory
|
||||||
|
// If screen_res is NULL, it's assumed to be the same as script_res
|
||||||
|
// If video_rect is NULL, it's assumed to have origin in (0,0) and same size as screen_res
|
||||||
|
PLUGIN_INTERFACE void renderer_set_resolution(EditorPluginRenderer *renderer, const SIZE *script_res, const SIZE *screen_res, const RECT *video_rect);
|
||||||
|
// Clears script and reinstates script resolution
|
||||||
|
PLUGIN_INTERFACE void renderer_clear(EditorPluginRenderer *renderer);
|
||||||
|
// Set wrap style
|
||||||
|
// Both arguments mandatory
|
||||||
|
PLUGIN_INTERFACE void renderer_set_wrap_style(EditorPluginRenderer *renderer, int wrap_style);
|
||||||
|
// Add a style definition
|
||||||
|
// All arguments mandatory
|
||||||
|
PLUGIN_INTERFACE void renderer_add_style(EditorPluginRenderer *renderer, const wchar_t *name, const wchar_t *fontname, double fontsize, COLORREF colors[4], BYTE alpha[4],
|
||||||
|
int bold, int italic, int underline, int strikeout, double scalex, double scaley, double spacing, double angle,
|
||||||
|
int borderstyle, double outline, double shadow, int alignment, const RECT *margins, int encoding, int relativeto);
|
||||||
|
// Add a dialogue line
|
||||||
|
// All arguments mandatory
|
||||||
|
PLUGIN_INTERFACE void renderer_add_dialogue(EditorPluginRenderer *renderer, int layer, int start, int end, const wchar_t *style, const wchar_t *name,
|
||||||
|
const RECT *margins, const wchar_t *effect, const wchar_t *text);
|
||||||
|
// Render a frame of subtitles laid over existing video
|
||||||
|
// time is the timestamp in milliseconds
|
||||||
|
// frame is a pointer to the 24 bpp RGB data to render over, assumed to have the screen_res dimensions, stride equal to width and top to bottom scanline ordering
|
||||||
|
PLUGIN_INTERFACE void renderer_render_overlay(EditorPluginRenderer *renderer, unsigned int time, BYTE *frame);
|
||||||
|
// Render a frame to an RGBA buffer
|
||||||
|
// time as above
|
||||||
|
// frame is a pointer to a buffer to contain the 32 bpp RGBA bitmap rendered; same assumptions as above
|
||||||
|
PLUGIN_INTERFACE void renderer_render_alpha(EditorPluginRenderer *renderer, unsigned int time, BYTE *frame);
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _i_defined_plugin_interface
|
||||||
|
#undef PLUGIN_INTERFACE
|
||||||
|
#undef _i_defined_plugin_interface
|
||||||
|
#endif
|
||||||
|
|
|
@ -52,6 +52,7 @@ function process_lines(meta, styles, lines, config)
|
||||||
out(string.format("Line %d: %s", i, lines[i].kind))
|
out(string.format("Line %d: %s", i, lines[i].kind))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
out("Finished dumping")
|
||||||
|
|
||||||
-- In the end, no modifications were done, so just return the original subtitle data
|
-- In the end, no modifications were done, so just return the original subtitle data
|
||||||
return lines
|
return lines
|
|
@ -32,7 +32,7 @@
|
||||||
-- positioning of karaoke.
|
-- positioning of karaoke.
|
||||||
|
|
||||||
-- It automatically includes and re-setups karaskel.lua, so you should not include that yourself!
|
-- It automatically includes and re-setups karaskel.lua, so you should not include that yourself!
|
||||||
include("karaskel-base.lua")
|
include("karaskel-base.auto3")
|
||||||
karaskel.engage_positioning = true
|
karaskel.engage_positioning = true
|
||||||
|
|
||||||
-- The interface here has been greatly simplified, there is only one function to override, do_syllable
|
-- The interface here has been greatly simplified, there is only one function to override, do_syllable
|
|
@ -28,11 +28,12 @@
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Aegisub Automation 4 Lua
|
-- Aegisub Automation 4 Lua
|
||||||
-- Wrapper for "advanced" karaskel
|
-- Nothing different between "regular" and "advanced" karaskel now, but auto3 will expect it
|
||||||
|
|
||||||
if not karaskel then
|
-- Compatibility hatch
|
||||||
karaskel = {}
|
if aegisub.lua_automation_version < 4 then
|
||||||
|
include("karaskel-adv.auto3")
|
||||||
|
return
|
||||||
end
|
end
|
||||||
karaskel.advanced = true
|
|
||||||
|
|
||||||
include("karaskel.lua")
|
include("karaskel.lua")
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
-- This file is meant as a support file for the various karaoke skeleton
|
-- This file is meant as a support file for the various karaoke skeleton
|
||||||
-- scripts, to avoid including unneeded code
|
-- scripts, to avoid including unneeded code
|
||||||
|
|
||||||
include("utils.lua")
|
include("utils.auto3")
|
||||||
|
|
||||||
-- karaskel
|
-- karaskel
|
||||||
-- This is a gloabl table defining various parameters, controlling what the
|
-- This is a gloabl table defining various parameters, controlling what the
|
|
@ -27,6 +27,13 @@
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
-- Automation 4 Lua compatibility script for Auto3 karaskel based scripts
|
-- Aegisub Automation 4 Lua
|
||||||
|
-- No "base" karaskel any longer, but auto3 scripts might expect it
|
||||||
|
|
||||||
-- TODO
|
-- Compatibility hatch
|
||||||
|
if aegisub.lua_automation_version < 4 then
|
||||||
|
include("karaskel-base.auto3")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
include("karaskel.lua")
|
|
@ -65,7 +65,7 @@
|
||||||
-- start_time - Start time of the syllable, in miliseconds, relative to the start of the line
|
-- start_time - Start time of the syllable, in miliseconds, relative to the start of the line
|
||||||
-- end_time - End time of the syllable, similar to start_time
|
-- end_time - End time of the syllable, similar to start_time
|
||||||
|
|
||||||
include("karaskel-base.lua")
|
include("karaskel-base.auto3")
|
||||||
|
|
||||||
-- Return a replacement text for a syllable
|
-- Return a replacement text for a syllable
|
||||||
function karaskel.do_syllable(meta, styles, config, line, syl)
|
function karaskel.do_syllable(meta, styles, config, line, syl)
|
|
@ -29,20 +29,10 @@
|
||||||
|
|
||||||
-- Aegisub Automation 4 Lua karaoke skeleton
|
-- Aegisub Automation 4 Lua karaoke skeleton
|
||||||
|
|
||||||
if version == 3 then
|
-- Compatibility hatch
|
||||||
-- Attempt to emulate
|
if aegisub.lua_automation_version < 4 then
|
||||||
-- This will only work if karaskel is being included after version has been defined
|
include("karaskel.auto3")
|
||||||
include("auto3-karaskel.lua")
|
return
|
||||||
|
|
||||||
version = nil
|
|
||||||
if name then
|
|
||||||
script_name = name
|
|
||||||
name = nil
|
|
||||||
end
|
|
||||||
if description then
|
|
||||||
script_description = description
|
|
||||||
description = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
include("utils.lua")
|
include("utils.lua")
|
||||||
|
|
|
@ -27,6 +27,12 @@
|
||||||
POSSIBILITY OF SUCH DAMAGE.
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
]]
|
]]
|
||||||
|
|
||||||
|
-- Compatibility hatch
|
||||||
|
if aegisub.lua_automation_version < 4 then
|
||||||
|
include "utils.auto3"
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- Make a shallow copy of a table
|
-- Make a shallow copy of a table
|
||||||
function table.copy(oldtab)
|
function table.copy(oldtab)
|
||||||
local newtab = {}
|
local newtab = {}
|
||||||
|
|
Loading…
Reference in a new issue