Style parsing implemented.

Originally committed to SVN as r2007.
This commit is contained in:
Rodrigo Braz Monteiro 2008-03-10 03:08:33 +00:00
parent bb31ddb1da
commit 437dbdc8f4
14 changed files with 839 additions and 114 deletions

View file

@ -171,6 +171,10 @@
RelativePath=".\include\aegilib\aegitime.h"
>
</File>
<File
RelativePath=".\include\aegilib\colour.h"
>
</File>
<File
RelativePath=".\include\aegilib\controller.h"
>
@ -215,6 +219,14 @@
RelativePath=".\include\aegilib\section_entry_dialogue.h"
>
</File>
<File
RelativePath=".\include\aegilib\section_entry_style.h"
>
</File>
<File
RelativePath=".\include\aegilib\tokenizer.h"
>
</File>
<File
RelativePath=".\include\aegilib\view.h"
>
@ -251,6 +263,10 @@
<Filter
Name="Misc"
>
<File
RelativePath=".\src\colour.cpp"
>
</File>
<File
RelativePath=".\src\exception.cpp"
>
@ -300,6 +316,10 @@
RelativePath=".\src\time.cpp"
>
</File>
<File
RelativePath=".\src\tokenizer.cpp"
>
</File>
</Filter>
<Filter
Name="Formats"
@ -312,6 +332,14 @@
RelativePath=".\src\formats\format_ass.h"
>
</File>
<File
RelativePath=".\src\formats\format_ass_dialogue.cpp"
>
</File>
<File
RelativePath=".\src\formats\format_ass_style.cpp"
>
</File>
</Filter>
</Files>
<Globals>

View file

@ -46,7 +46,9 @@
#include "manipulator.h"
#include "section.h"
#include "section_entry_dialogue.h"
#include "section_entry_style.h"
#include "aegitime.h"
#include "colour.h"
//////////

View file

@ -0,0 +1,68 @@
// 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
//
#pragma once
#include "aegistring.h"
namespace Aegilib {
// Colour class
class Colour {
private:
unsigned char r, g, b, a;
public:
Colour ();
Colour (unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha=0);
Colour (int red,int green,int blue,int alpha=0);
void SetRed(unsigned char red) { r = red; }
void SetGreen(unsigned char green) { g = green; }
void SetBlue(unsigned char blue) { b = blue; }
void SetAlpha(unsigned char alpha) { a = alpha; }
void SetRed(int red);
void SetGreen(int green);
void SetBlue(int blue);
void SetAlpha(int alpha);
unsigned char GetRed() const { return r; }
unsigned char GetGreen() const { return g; }
unsigned char GetBlue() const { return b; }
unsigned char GetAlpha() const { return a; }
void Parse(String str,bool reverse);
};
};

View file

@ -49,7 +49,8 @@ namespace Aegilib {
Section_Already_Exists,
Unknown_Format,
Parse_Error,
Unsupported_Format_Feature
Unsupported_Format_Feature,
Invalid_Token
};
Exception(ExceptionList code);

View file

@ -62,6 +62,7 @@ namespace Aegilib {
virtual bool HasTime() const { return false; }
virtual bool HasFrame() const { return false; }
virtual bool HasStyle() const { return false; }
virtual bool HasActor() const { return false; }
virtual bool HasMargins() const { return false; }
// Read accessors
@ -70,6 +71,12 @@ namespace Aegilib {
virtual Time GetEndTime() const { ThrowUnsupported(); return 0; }
virtual int GetStartFrame() const { ThrowUnsupported(); return 0; }
virtual int GetEndFrame() const { ThrowUnsupported(); return 0; }
virtual bool IsComment() const { ThrowUnsupported(); return false; }
virtual int GetLayer() const { ThrowUnsupported(); return 0; }
virtual int GetMargin(int n) const { ThrowUnsupported(); return n; }
virtual String GetStyle() const { ThrowUnsupported(); return L""; }
virtual String GetActor() const { ThrowUnsupported(); return L""; }
virtual String GetUserField() const { ThrowUnsupported(); return L""; }
// Write acessors
virtual void SetText(String text) { (void) text; ThrowUnsupported(); }
@ -77,6 +84,12 @@ namespace Aegilib {
virtual void SetEndTime(Time end) { (void) end; ThrowUnsupported(); }
virtual void SetStartFrame(int start) { (void) start; ThrowUnsupported(); }
virtual void SetEndFrame(int end) { (void) end; ThrowUnsupported(); }
virtual void SetComment(bool isComment) { (void) isComment; ThrowUnsupported(); }
virtual void SetLayer(int layer) { (void) layer; ThrowUnsupported(); }
virtual void SetMargin(int margin,int value) { (void) margin; (void) value; ThrowUnsupported(); }
virtual void SetStyle(String style) { (void) style; ThrowUnsupported(); }
virtual void SetActor(String actor) { (void) actor; ThrowUnsupported(); }
virtual void SetUserField(String userField) { (void) userField; ThrowUnsupported(); }
};
};

View file

@ -0,0 +1,67 @@
// 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
//
#pragma once
#include "exception.h"
#include "colour.h"
#include "section_entry.h"
namespace Aegilib {
// Style class
class SectionEntryStyle : public SectionEntry {
private:
const static bool dodgeWarning = true;
void ThrowUnsupported() const { if (dodgeWarning) throw Exception(Exception::Unsupported_Format_Feature); }
public:
// Destructor
virtual ~SectionEntryStyle() {}
// Type
SectionEntryType GetType() const { return SECTION_ENTRY_STYLE; }
SectionEntryStyle *GetAsStyle() { return this; }
// Read accessors
virtual String GetName() const=0;
virtual String GetFontName() const { ThrowUnsupported(); return L""; }
virtual float GetFontSize() const { ThrowUnsupported(); return 0.0f; }
virtual Colour GetColour(int n) const { (void) n; ThrowUnsupported(); return Colour(); }
virtual int GetMargin(int n) const { (void) n; ThrowUnsupported(); return 0; }
};
};

View file

@ -0,0 +1,64 @@
// 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
//
#pragma once
#include "aegistring.h"
// Prototypes
class wxStringTokenizer;
namespace Aegilib {
// Tokenizer class
class Tokenizer {
private:
wxStringTokenizer *tkn;
public:
Tokenizer(String string,String token);
~Tokenizer();
bool HasMore();
int GetPosition();
String GetString();
int GetInt();
long GetLong();
float GetFloat();
double GetDouble();
bool GetBool();
};
};

108
aegilib/src/colour.cpp Normal file
View file

@ -0,0 +1,108 @@
// 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 "aegilib.h"
using namespace Aegilib;
////////////////
// Constructors
Colour::Colour ()
{
r = g = b = a = 0;
}
Colour::Colour (unsigned char red,unsigned char green,unsigned char blue,unsigned char alpha)
{
r = red;
g = green;
b = blue;
a = alpha;
}
Colour::Colour (int red,int green,int blue,int alpha)
{
SetRed(red);
SetGreen(green);
SetBlue(blue);
SetAlpha(alpha);
}
////////////////////////
// Set colour component
void Colour::SetRed(int red) { r = (unsigned char) MID(0,red,255); }
void Colour::SetGreen(int green) { g = (unsigned char) MID(0,green,255); }
void Colour::SetBlue(int blue) { b = (unsigned char) MID(0,blue,255); }
void Colour::SetAlpha(int alpha) { a = (unsigned char) MID(0,alpha,255); }
//////////////
// Parse text
void Colour::Parse(String value,bool reverse)
{
// Prepare
unsigned char c;
char ostr[12];
ostr[11]=0;
unsigned long outval;
int oindex=11;
bool ishex=false;
// Determines whether it is hexadecimal or decimal
for(int i=(int)value.Len()-1;i>=0&&oindex>=0;i--) {
c=(char) value[i];
if (isxdigit(c) || c=='-') {
ostr[--oindex] = c;
if (c>='A') ishex = true;
}
else if (c == 'H' || c == 'h') ishex = true;
}
// Convert to decimal
outval=strtoul(ostr+oindex,0,ishex?16:10);
// Split components
b = (unsigned char)(outval & 0xFF);
g = (unsigned char)((outval>>8) & 0xFF);
r = (unsigned char)((outval>>16)& 0xFF);
a = (unsigned char)((outval>>24)& 0xFF);
// Reverse
if (reverse) {
unsigned char aux = r;
r = b;
b = aux;
}
}

View file

@ -57,6 +57,7 @@ String Exception::GetMessage()
case Unknown_Format: return L"The specified file format is unknown.";
case Parse_Error: return L"Parse error.";
case Unsupported_Format_Feature: return L"This feature is not supported by this format.";
case Invalid_Token: return L"Invalid type for this token.";
}
return L"Invalid code.";
}

View file

@ -156,7 +156,18 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version)
// Styles
else if (group == _T("V4+ Styles")) {
if (data.Left(6) == _T("Style:")) {
StyleASS *style = new StyleASS(data,version);
final = style;
// Debug
wxString out = style->GetName() + _T(": ") + style->GetFontName() + _T(", ") + wxString::Format(_T("(%i,%i,%i)"),style->GetColour(0).GetRed(),style->GetColour(0).GetGreen(),style->GetColour(0).GetBlue());
std::cout << out.mb_str(wxConvUTF8) << std::endl;
}
if (data.Left(7) == _T("Format:")) {
// TODO
//entry = new AssEntry(_T("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding"));
}
}
// Script info
@ -244,113 +255,3 @@ void FormatHandlerASS::ProcessGroup(String cur,String &curGroup,int &version) {
}
}
}
////////////////////////////
// ASS dialogue constructor
DialogueASS::DialogueASS(String data,int version)
{
// Try parsing with all different versions
bool valid = false;
for (int count=0;!valid && count < 3;count++) {
valid = Parse(data,version);
version++;
if (version > 2) version = 0;
}
}
//////////////////
// Parse ASS Data
bool DialogueASS::Parse(wxString rawData, int version)
{
size_t pos = 0;
wxString temp;
// Get type
if (rawData.StartsWith(_T("Dialogue:"))) {
comment = false;
pos = 10;
}
else if (rawData.StartsWith(_T("Comment:"))) {
comment = true;
pos = 9;
}
else return false;
wxStringTokenizer tkn(rawData.Mid(pos),_T(","),wxTOKEN_RET_EMPTY_ALL);
if (!tkn.HasMoreTokens()) return false;
// Get first token and see if it has "Marked=" in it
temp = tkn.GetNextToken().Trim(false).Trim(true);
if (temp.Lower().StartsWith(_T("marked="))) version = 0;
else if (version == 0) version = 1;
// Get layer number
if (version == 0) layer = 0;
else {
long templ;
temp.ToLong(&templ);
layer = templ;
}
// Get start time
if (!tkn.HasMoreTokens()) return false;
start.Parse(tkn.GetNextToken());
// Get end time
if (!tkn.HasMoreTokens()) return false;
end.Parse(tkn.GetNextToken());
// Get style
if (!tkn.HasMoreTokens()) return false;
style = tkn.GetNextToken();
style.Trim(true);
style.Trim(false);
// Get actor
if (!tkn.HasMoreTokens()) return false;
actor = tkn.GetNextToken();
actor.Trim(true);
actor.Trim(false);
// Get margins
for (int i=0;i<3;i++) {
if (!tkn.HasMoreTokens()) return false;
long templ;
tkn.GetNextToken().Trim(false).Trim(true).ToLong(&templ);
margin[i] = templ;
}
// Get bottom margin
if (version == 1) margin[3] = margin[2];
bool rollBack = false;
if (version == 2) {
if (!tkn.HasMoreTokens()) return false;
wxString oldTemp = temp;
temp = tkn.GetNextToken().Trim(false).Trim(true);
if (!temp.IsNumber()) {
version = 1;
rollBack = true;
}
else {
long templ;
temp.ToLong(&templ);
margin[3] = templ;
}
}
// Get effect
if (!rollBack) {
if (!tkn.HasMoreTokens()) return false;
temp = tkn.GetNextToken();
}
effect = temp;
effect.Trim(true);
effect.Trim(false);
// Get text
text = rawData.Mid(pos+tkn.GetPosition());
return true;
}

View file

@ -38,6 +38,7 @@
#include "format_handler.h"
#include "section.h"
#include "section_entry_dialogue.h"
#include "section_entry_style.h"
namespace Aegilib {
@ -84,13 +85,13 @@ namespace Aegilib {
Time start,end;
int margin[4];
int layer;
bool comment;
bool isComment;
bool Parse(String data,int version);
public:
// Constructors
DialogueASS() {}
DialogueASS();
DialogueASS(String data,int version);
// Capabilities
@ -103,11 +104,64 @@ namespace Aegilib {
String GetText() const { return text; }
Time GetStartTime() const { return start; }
Time GetEndTime() const { return end; }
bool IsComment() const { return isComment; }
int GetLayer() const { return layer; }
int GetMargin(int n) const { return margin[n]; }
String GetStyle() const { return style; }
String GetActor() const { return actor; }
String GetUserField() const { return effect; }
// Write acessors
void SetText(String setText) { text = setText; }
void SetStartTime(Time setStart) { start = setStart; }
void SetEndTime(Time setEnd) { end = setEnd; }
void SetComment(bool _isComment) { isComment = _isComment; }
void SetLayer(int _layer) { layer = _layer; }
void SetMargin(int _margin,int value) { margin[_margin] = value; }
void SetStyle(String _style) { style = _style; }
void SetUserField(String userField) { effect = userField; }
};
// Style
class StyleASS : public SectionEntryStyle {
private:
String name;
String font;
float fontSize;
Colour colour[5]; // 0 = Primary, 1 = Secondary, 2 = Tertiary, 3 = Outline, 4 = Shadow
int margin[4];
bool bold;
bool italic;
bool underline;
bool strikeout;
int borderStyle;
int alignment;
int encoding;
int relativeTo;
float scalex;
float scaley;
float spacing;
float angle;
float outline_w;
float shadow_w;
bool Parse(String data,int version);
public:
// Constructors
StyleASS();
StyleASS(String data,int version);
// Read accessors
String GetName() const { return name; }
String GetFontName() const { return font; }
float GetFontSize() const { return fontSize; }
Colour GetColour(int n) const { return colour[n]; }
int GetMargin(int n) const { return margin[n]; }
};
};

View file

@ -0,0 +1,145 @@
// 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 "format_ass.h"
#include "tokenizer.h"
using namespace Aegilib;
////////////////
// Constructors
DialogueASS::DialogueASS()
{
for (int i=0;i<4;i++) margin[i] = 0;
layer = 0;
isComment = false;
}
DialogueASS::DialogueASS(String data,int version)
{
// Try parsing with all different versions
bool valid = false;
for (int count=0;!valid && count < 3;count++) {
valid = Parse(data,version);
version++;
if (version > 2) version = 0;
}
if (!valid) throw Exception(Exception::Parse_Error);
}
//////////////////
// Parse ASS Data
bool DialogueASS::Parse(wxString rawData, int version)
{
size_t pos = 0;
wxString temp;
// Get type
if (rawData.StartsWith(_T("Dialogue:"))) {
isComment = false;
pos = 10;
}
else if (rawData.StartsWith(_T("Comment:"))) {
isComment = true;
pos = 9;
}
else return false;
try {
Tokenizer tkn(rawData.Mid(pos),_T(","));
// Get first token and see if it has "Marked=" in it
temp = tkn.GetString().Trim(false).Trim(true);
if (temp.Lower().StartsWith(_T("marked="))) version = 0;
else if (version == 0) version = 1;
// Get layer number
if (version == 0) layer = 0;
else {
long templ;
temp.ToLong(&templ);
layer = templ;
}
// Get times
start.Parse(tkn.GetString());
end.Parse(tkn.GetString());
// Get style
style = tkn.GetString();
style.Trim(true);
style.Trim(false);
// Get actor
actor = tkn.GetString();
actor.Trim(true);
actor.Trim(false);
// Get margins
for (int i=0;i<3;i++) margin[i] = tkn.GetInt();
// Get bottom margin
if (version == 1) margin[3] = margin[2];
bool rollBack = false;
if (version == 2) {
wxString oldTemp = temp;
temp = tkn.GetString().Trim(false).Trim(true);
if (!temp.IsNumber()) {
version = 1;
rollBack = true;
}
else {
long templ;
temp.ToLong(&templ);
margin[3] = templ;
}
}
// Get effect
if (!rollBack) temp = tkn.GetString();
effect = temp;
effect.Trim(true);
effect.Trim(false);
// Get text
text = rawData.Mid(pos+tkn.GetPosition());
}
catch (...) {
return false;
}
return true;
}

View file

@ -0,0 +1,164 @@
// 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 "format_ass.h"
#include "tokenizer.h"
using namespace Aegilib;
////////////////
// Constructors
StyleASS::StyleASS()
{
}
StyleASS::StyleASS(String data,int version)
{
// Try parsing with all different versions
bool valid = false;
for (int count=0;!valid && count < 3;count++) {
valid = Parse(data,version);
version++;
if (version > 2) version = 0;
}
if (!valid) throw Exception(Exception::Parse_Error);
}
/////////
// Parse
bool StyleASS::Parse(String data,int version)
{
try {
// Tokenize
wxString temp;
Tokenizer tkn(data.Trim(false).Mid(6),_T(","));
// Read name
name = tkn.GetString();
name.Trim(true);
name.Trim(false);
// Read font name and size
font = tkn.GetString();
font.Trim(true);
font.Trim(false);
fontSize = tkn.GetFloat();
// Read colours
for (int i=0;i<5;i++) {
if ((i == 4 && version == 0) || (i == 2 && version != 0)) colour[i] = colour[i-1];
else {
colour[i].Parse(tkn.GetString(),true);
}
}
// Read bold and italics
bold = tkn.GetBool();
italic = tkn.GetBool();
// ASS
if (version != 0) {
// Read underline, strikeout, scale, spacing and angle
underline = tkn.GetBool();
strikeout = tkn.GetBool();
scalex = tkn.GetFloat();
scaley = tkn.GetFloat();
spacing = tkn.GetFloat();
angle = tkn.GetFloat();
}
else {
// SSA defaults
underline = false;
strikeout = false;
scalex = 100;
scaley = 100;
spacing = 0;
angle = 0.0;
}
// Read border style and widths
borderStyle = tkn.GetInt();
outline_w = tkn.GetFloat();
shadow_w = tkn.GetFloat();
// Read alignment
int align = tkn.GetInt();
if (version == 0) {
switch(align) {
case 1: alignment = 1; break;
case 2: alignment = 2; break;
case 3: alignment = 3; break;
case 5: alignment = 7; break;
case 6: alignment = 8; break;
case 7: alignment = 9; break;
case 9: alignment = 4; break;
case 10: alignment = 5; break;
case 11: alignment = 6; break;
default: alignment = 2; break;
}
}
else alignment = align;
// Read margins
for (int i=0;i<4;i++) {
if (i == 3 && version < 2) margin[i] = margin[i-1];
else {
margin[i] = tkn.GetInt();
}
}
// Read and discard alpha level
if (version == 0) {
tkn.GetString();
}
// Read encoding
encoding = tkn.GetInt();
// Read relative to
if (version == 2) {
relativeTo = tkn.GetInt();
}
// End
if (tkn.HasMore()) return false;
return true;
}
catch (...) {
return false;
}
}

109
aegilib/src/tokenizer.cpp Normal file
View file

@ -0,0 +1,109 @@
// 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 "tokenizer.h"
#include "exception.h"
#include <wx/tokenzr.h>
using namespace Aegilib;
///////////////
// Constructor
Tokenizer::Tokenizer(String string,String token)
{
tkn = new wxStringTokenizer(string,token,wxTOKEN_RET_EMPTY_ALL);
}
Tokenizer::~Tokenizer()
{
delete tkn;
}
////////////
// Has more
bool Tokenizer::HasMore()
{
return tkn->HasMoreTokens();
}
////////////////
// Get position
int Tokenizer::GetPosition()
{
return (int)tkn->GetPosition();
}
/////////////
// Get token
String Tokenizer::GetString()
{
return tkn->GetNextToken();
}
int Tokenizer::GetInt()
{
long value;
wxString temp = tkn->GetNextToken();
temp.ToLong(&value);
return (int) value;
}
long Tokenizer::GetLong()
{
long value;
wxString temp = tkn->GetNextToken();
temp.ToLong(&value);
return value;
}
float Tokenizer::GetFloat()
{
double value;
wxString temp = tkn->GetNextToken();
temp.ToDouble(&value);
return (float) value;
}
double Tokenizer::GetDouble()
{
double value;
wxString temp = tkn->GetNextToken();
temp.ToDouble(&value);
return value;
}
bool Tokenizer::GetBool()
{
long value;
wxString temp = tkn->GetNextToken();
temp.ToLong(&value);
return value != 0;
}