diff --git a/aegilib/aegilib.vcproj b/aegilib/aegilib.vcproj
index d1213ac3a..4285eff65 100644
--- a/aegilib/aegilib.vcproj
+++ b/aegilib/aegilib.vcproj
@@ -235,6 +235,10 @@
RelativePath=".\include\aegilib\utils.h"
>
+
+
@@ -344,6 +348,10 @@
RelativePath=".\src\utils.cpp"
>
+
+
@@ -43,13 +44,26 @@
using namespace Aegilib;
-//////////////
-// Extensions
+///////
+// SSA
+StringArray FormatSSA::GetReadExtensions() const
+{
+ StringArray final;
+ final.push_back(L".ssa");
+ return final;
+}
+StringArray FormatSSA::GetWriteExtensions() const
+{
+ return GetReadExtensions();
+}
+
+
+///////
+// ASS
StringArray FormatASS::GetReadExtensions() const
{
StringArray final;
final.push_back(L".ass");
- final.push_back(L".ssa");
return final;
}
StringArray FormatASS::GetWriteExtensions() const
@@ -58,10 +72,24 @@ StringArray FormatASS::GetWriteExtensions() const
}
+////////
+// ASS2
+StringArray FormatASS2::GetReadExtensions() const
+{
+ StringArray final;
+ final.push_back(L".ass");
+ return final;
+}
+StringArray FormatASS2::GetWriteExtensions() const
+{
+ return GetReadExtensions();
+}
+
+
///////////////
// Constructor
-FormatHandlerASS::FormatHandlerASS(Model &_model)
-: model(_model)
+FormatHandlerASS::FormatHandlerASS(Model &_model,int version)
+: model(_model), formatVersion(version)
{
}
@@ -296,7 +324,20 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
void FormatHandlerASS::WriteSection(TextFileWriter &writer,SectionPtr section)
{
// Write name
- writer.WriteLineToFile(_T("[") + section->GetName() + _T("]"));
+ wxString name = section->GetName();
+ writer.WriteLineToFile(_T("[") + name + _T("]"));
+
+ // Write program and library credits
+ if (name == _T("Script Info")) {
+ wxString programName = GetHostApplicationName();
+ wxString programURL = GetHostApplicationURL();
+ wxString libVersion = GetLibraryVersionString();
+ wxString libURL = GetLibraryURL();
+ writer.WriteLineToFile(_T("; Script generated by ") + programName);
+ if (!programURL.IsEmpty()) writer.WriteLineToFile(_T("; ") + programURL);
+ writer.WriteLineToFile(_T("; With ") + libVersion);
+ if (programURL != libURL) writer.WriteLineToFile(_T("; ") + libURL);
+ }
// Write properties
size_t props = section->GetPropertyCount();
@@ -310,6 +351,6 @@ void FormatHandlerASS::WriteSection(TextFileWriter &writer,SectionPtr section)
for (size_t i=0;iGetEntry(i);
shared_ptr serial = dynamic_pointer_cast(entry);
- writer.WriteLineToFile(serial->ToText());
+ writer.WriteLineToFile(serial->ToText(formatVersion));
}
}
diff --git a/aegilib/src/formats/format_ass.h b/aegilib/src/formats/format_ass.h
index f7cd072c7..b329d0cb8 100644
--- a/aegilib/src/formats/format_ass.h
+++ b/aegilib/src/formats/format_ass.h
@@ -46,36 +46,35 @@ namespace Aegilib {
class Model;
class TextFileWriter;
+ // Interface to serialize classes
class SerializeText {
public:
virtual ~SerializeText(){}
- virtual String ToText() const=0;
+ virtual String ToText(int param) const=0;
};
// Advanced Substation Alpha format handler
class FormatHandlerASS : public FormatHandler {
private:
Model &model;
+ int formatVersion;
SectionEntryPtr MakeEntry(const String &data,SectionPtr section,int version);
void ProcessGroup(String cur,String &curGroup,int &version);
void WriteSection(TextFileWriter &writer,SectionPtr section);
public:
- FormatHandlerASS(Model &model);
+ FormatHandlerASS(Model &model,int version);
~FormatHandlerASS();
void Load(wxInputStream &file,const String encoding);
void Save(wxOutputStream &file,const String encoding);
};
- // Advanced Substation Alpha format
- class FormatASS : public Format {
+ // Advanced Substation Alpha format base class
+ class FormatASSFamily : public Format {
public:
- String GetName() const { return L"Advanced Substation Alpha"; }
- StringArray GetReadExtensions() const;
- StringArray GetWriteExtensions() const;
- FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model)); }
+ virtual ~FormatASSFamily() {}
bool CanStoreText() const { return true; }
bool CanUseTime() const { return true; }
@@ -85,6 +84,33 @@ namespace Aegilib {
bool HasActors() const { return true; }
};
+ // Substation Alpha
+ class FormatSSA : public FormatASSFamily {
+ public:
+ FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,0)); }
+ String GetName() const { return L"Substation Alpha"; }
+ StringArray GetReadExtensions() const;
+ StringArray GetWriteExtensions() const;
+ };
+
+ // Advanced Substation Alpha
+ class FormatASS : public FormatASSFamily {
+ public:
+ FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,1)); }
+ String GetName() const { return L"Advanced Substation Alpha"; }
+ StringArray GetReadExtensions() const;
+ StringArray GetWriteExtensions() const;
+ };
+
+ // Advanced Substation Alpha 2
+ class FormatASS2 : public FormatASSFamily {
+ public:
+ FormatHandlerPtr GetHandler(Model &model) const { return FormatHandlerPtr(new FormatHandlerASS(model,2)); }
+ String GetName() const { return L"Advanced Substation Alpha 2"; }
+ StringArray GetReadExtensions() const;
+ StringArray GetWriteExtensions() const;
+ };
+
// Dialogue
class DialogueASS : public SectionEntryDialogue, public SerializeText {
private:
@@ -98,7 +124,7 @@ namespace Aegilib {
bool isComment;
bool Parse(String data,int version);
- String ToText() const;
+ String ToText(int param) const;
public:
// Constructors
@@ -161,9 +187,9 @@ namespace Aegilib {
float shadow_w;
bool Parse(String data,int version);
- int AlignSSAtoASS(int ssaAlignment);
- int AlignASStoSSA(int assAlignment);
- String ToText() const;
+ int AlignSSAtoASS(int ssaAlignment) const;
+ int AlignASStoSSA(int assAlignment) const;
+ String ToText(int param) const;
public:
// Constructors
diff --git a/aegilib/src/formats/format_ass_dialogue.cpp b/aegilib/src/formats/format_ass_dialogue.cpp
index 3131da4d9..5da81829f 100644
--- a/aegilib/src/formats/format_ass_dialogue.cpp
+++ b/aegilib/src/formats/format_ass_dialogue.cpp
@@ -138,8 +138,33 @@ bool DialogueASS::Parse(wxString rawData, int version)
/////////////
// Serialize
-String DialogueASS::ToText() const
+String DialogueASS::ToText(int version) const
{
- String final = L"Dialogue";
+ // Prepare
+ wxString final = _T("");
+
+ // Write comment or dialogue
+ if (isComment) final = _T("Comment: ");
+ else final = _T("Dialogue: ");
+
+ // Write layer or marked
+ if (version >= 1) final += wxString::Format(_T("%01i,"),layer);
+ else final += _T("Marked=0,");
+
+ // Write times, style and actor
+ final += start.GetString(2,1) + _T(",") + end.GetString(2,1) + _T(",") + style + _T(",") + actor + _T(",");
+
+ // Write margins
+ if (version <= 1) final += wxString::Format(_T("%04i,%04i,%04i,"),margin[0],margin[1],margin[2]);
+ else final += wxString::Format(_T("%04i,%04i,%04i,%04i,"),margin[0],margin[1],margin[2],margin[3]);
+
+ // Write effect and text
+ final += effect + _T(",") + text;
+
+ // Make sure that final has no line breaks
+ final.Replace(_T("\n"),_T(""));
+ final.Replace(_T("\r"),_T(""));
+
+ // Return final
return final;
}
diff --git a/aegilib/src/formats/format_ass_style.cpp b/aegilib/src/formats/format_ass_style.cpp
index 26016e728..9975dbcea 100644
--- a/aegilib/src/formats/format_ass_style.cpp
+++ b/aegilib/src/formats/format_ass_style.cpp
@@ -35,6 +35,7 @@
#include "format_ass.h"
#include "tokenizer.h"
+#include "utils.h"
using namespace Aegilib;
@@ -124,6 +125,7 @@ bool StyleASS::Parse(String data,int version)
encoding = tkn.GetInt();
// Read relative to
+ relativeTo = 0;
if (version == 2) relativeTo = tkn.GetInt();
// End
@@ -139,7 +141,7 @@ bool StyleASS::Parse(String data,int version)
////////////////////////////////
// Convert SSA alignment to ASS
-int StyleASS::AlignSSAtoASS(int align)
+int StyleASS::AlignSSAtoASS(int align) const
{
switch(align) {
case 1: return 1;
@@ -158,17 +160,69 @@ int StyleASS::AlignSSAtoASS(int align)
////////////////////////////////
// Convert ASS alignment to SSA
-int StyleASS::AlignASStoSSA(int assAlignment)
+int StyleASS::AlignASStoSSA(int align) const
{
- // TODO
- return assAlignment;
+ switch (align) {
+ case 1: return 1;
+ case 2: return 2;
+ case 3: return 3;
+ case 4: return 9;
+ case 5: return 10;
+ case 6: return 11;
+ case 7: return 5;
+ case 8: return 6;
+ case 9: return 7;
+ default: return 2;
+ }
}
/////////////
// Serialize
-String StyleASS::ToText() const
+String StyleASS::ToText(int version) const
{
- String final = L"Style";
+ // Final string
+ wxString final;
+
+ // Calculate colour offset
+ int cOff = 0;
+ if (version >= 1) cOff = 1;
+
+ // Calculate alignment
+ int align = alignment;
+ if (version == 0) align = AlignASStoSSA(align);
+
+ // Name, font, fontsize, colours, bold, italics
+ final = wxString::Format(_T("Style: %s,%s,%s,%s,%s,%s,%s,%i,%i,"),
+ name.c_str(), font.c_str(), PrettyFloatD(fontSize).c_str(),
+ colour[0].GetVBHex(true,true,false).c_str(), colour[1].GetVBHex(true,true,false).c_str(),
+ colour[2+cOff].GetVBHex(true,true,false).c_str(), colour[3+cOff].GetVBHex(true,true,false).c_str(),
+ (bold? -1 : 0), (italic ? -1 : 0));
+
+ // ASS-only
+ final += wxString::Format(_T("%i,%i,%s,%s,%s,%s,"),
+ (underline?-1:0),(strikeout?-1:0),PrettyFloatD(scalex).c_str(),PrettyFloatD(scaley).c_str(),
+ PrettyFloatD(spacing).c_str(),PrettyFloatD(angle).c_str());
+
+
+ // Borderstyle, outline width, shadow width, alignment, first three margins
+ final += wxString::Format(_T("%i,%s,%s,%i,%i,%i,%i,"),
+ borderStyle,PrettyFloatD(outline_w).c_str(),PrettyFloatD(shadow_w).c_str(),
+ align,margin[0],margin[1],margin[2]);
+
+ // Fourth margin for ASS2 only
+ if (version == 2) final += wxString::Format(_T("%i,"),margin[3]);
+
+ // Alpha level for SSA only
+ // TODO: write something relevant?
+ if (version == 0) final += wxString::Format(_T("%i,"),0);
+
+ // Encoding
+ final += wxString::Format(_T("%i"),encoding);
+
+ // Relative-to for ASS2 only
+ if (version == 2) final += wxString::Format(_T(",%i"),relativeTo);
+
+ // Done
return final;
}
diff --git a/aegilib/src/text_file_writer.cpp b/aegilib/src/text_file_writer.cpp
index 575881080..b80e9e02a 100644
--- a/aegilib/src/text_file_writer.cpp
+++ b/aegilib/src/text_file_writer.cpp
@@ -48,16 +48,7 @@ TextFileWriter::TextFileWriter(wxOutputStream &stream,String enc)
{
// Setup
IsFirst = true;
-
- // Set encoding
- encoding = enc;
- if (encoding == _T("Local")) conv = shared_ptr (wxConvCurrent,NullDeleter());
- else {
- if (encoding.IsEmpty()) encoding = _T("UTF-8");
- if (encoding == _T("US-ASCII")) encoding = _T("ISO-8859-1");
- conv = shared_ptr (new wxCSConv(encoding));
- IsUnicode = encoding.Left(3) == _T("UTF");
- }
+ SetEncoding(enc);
}
@@ -103,12 +94,20 @@ void TextFileWriter::WriteLineToFile(Aegilib::String line,bool addLineBreak) {
////////////////
// Set encoding
-void TextFileWriter::SetEncoding() {
+void TextFileWriter::SetEncoding(String enc) {
// Prepare
Is16 = false;
- // UTF-16
- if (encoding.Left(6) == _T("UTF-16")) {
- Is16 = true;
+ // Set encoding
+ encoding = enc;
+ if (encoding == _T("Local")) conv = shared_ptr (wxConvCurrent,NullDeleter());
+ else {
+ if (encoding.IsEmpty()) encoding = _T("UTF-8");
+ if (encoding == _T("US-ASCII")) encoding = _T("ISO-8859-1");
+ conv = shared_ptr (new wxCSConv(encoding));
+ IsUnicode = encoding.Left(3) == _T("UTF");
+ if (encoding.Left(6) == _T("UTF-16")) {
+ Is16 = true;
+ }
}
}
diff --git a/aegilib/src/text_file_writer.h b/aegilib/src/text_file_writer.h
index 8d24562ba..eebcfab7a 100644
--- a/aegilib/src/text_file_writer.h
+++ b/aegilib/src/text_file_writer.h
@@ -50,7 +50,7 @@ namespace Aegilib {
bool IsFirst;
bool IsUnicode;
- void SetEncoding();
+ void SetEncoding(String encoding);
public:
TextFileWriter(wxOutputStream &stream,String encoding=_T(""));
diff --git a/aegilib/src/time.cpp b/aegilib/src/time.cpp
index 53bb59ec5..a53602133 100644
--- a/aegilib/src/time.cpp
+++ b/aegilib/src/time.cpp
@@ -39,7 +39,7 @@ using namespace Aegilib;
//////////////////////
// Generates a string
-String Time::GetString(int ms_precision,int h_precision)
+String Time::GetString(int ms_precision,int h_precision) const
{
// Enforce sanity
ms_precision = Mid(0,ms_precision,3);
diff --git a/aegilib/src/utils.cpp b/aegilib/src/utils.cpp
index e6838508b..164c99796 100644
--- a/aegilib/src/utils.cpp
+++ b/aegilib/src/utils.cpp
@@ -47,3 +47,38 @@ int Aegilib::StringToInt(const String &str)
str.ToLong(&temp);
return (int) temp;
}
+
+
+////////////////
+// Pretty float
+String Aegilib::PrettyFloat(String src) {
+ if (src.Contains(_T("."))) {
+ size_t len = src.Length();
+ while (src.Right(1) == _T("0")) {
+ len--;
+ src.Truncate(len);
+ }
+ if (src.Right(1) == _T(".")) {
+ len--;
+ src.Truncate(len);
+ }
+ }
+ return src;
+}
+
+String Aegilib::PrettyFloatF(float src) { return Aegilib::PrettyFloat(wxString::Format(_T("%f"),src)); }
+String Aegilib::PrettyFloatD(double src) { return Aegilib::PrettyFloat(wxString::Format(_T("%f"),src)); }
+
+
+///////////////////
+// Float to string
+String Aegilib::FloatToString(double value) {
+ return PrettyFloat(wxString::Format(_T("%f"),value));
+}
+
+
+/////////////////
+// Int to string
+String Aegilib::IntegerToString(int value) {
+ return wxString::Format(_T("%i"),value);
+}
diff --git a/aegilib/src/version.cpp b/aegilib/src/version.cpp
new file mode 100644
index 000000000..aebaa5f3f
--- /dev/null
+++ b/aegilib/src/version.cpp
@@ -0,0 +1,82 @@
+// Copyright (c) 2008, Rodrigo Braz Monteiro
+// 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/AEGILIB
+//
+// Website: http://www.aegisub.net
+// Contact: mailto:amz@aegisub.net
+//
+
+
+#include "version.h"
+#include "tr1.h"
+using namespace Aegilib;
+
+
+////////////////
+// Library data
+String Aegilib::GetLibraryName()
+{
+ return _T("Aegilib");
+}
+String Aegilib::GetLibraryVersionString()
+{
+ return _T("Aegilib v0.x - EXPERIMENTAL");
+}
+String Aegilib::GetLibraryURL()
+{
+ return _T("http://www.aegisub.net");
+}
+
+
+/////////////////////////
+// Host application data
+static shared_ptr hostName;
+static shared_ptr hostURL;
+
+void Aegilib::SetHostApplicationName(const String name)
+{
+ if (!hostName) hostName = shared_ptr (new String());
+ *hostName = name;
+}
+void Aegilib::SetHostApplicationURL(const String url)
+{
+ if (!hostURL) hostName = shared_ptr (new String());
+ *hostURL = url;
+}
+String Aegilib::GetHostApplicationName()
+{
+ if (hostName) return *hostName;
+ return L"unknown application";
+}
+String Aegilib::GetHostApplicationURL()
+{
+ if (hostURL) return *hostURL;
+ return L"";
+}
diff --git a/aegilib/test/src/main.cpp b/aegilib/test/src/main.cpp
index 54bae5213..11518d6f3 100644
--- a/aegilib/test/src/main.cpp
+++ b/aegilib/test/src/main.cpp
@@ -48,6 +48,7 @@ int main () {
try {
// Set up the lib
FormatManager::InitializeFormats();
+ Aegilib::SetHostApplicationName(L"Aegilib test program");
// Subtitles model
Model subs;