diff --git a/aegilib/aegilib.vcproj b/aegilib/aegilib.vcproj index b3f8d8fc8..9c7d8bfef 100644 --- a/aegilib/aegilib.vcproj +++ b/aegilib/aegilib.vcproj @@ -171,6 +171,10 @@ RelativePath=".\include\aegilib\aegitime.h" > + + @@ -215,6 +219,14 @@ RelativePath=".\include\aegilib\section_entry_dialogue.h" > + + + + @@ -251,6 +263,10 @@ + + @@ -300,6 +316,10 @@ RelativePath=".\src\time.cpp" > + + + + + + diff --git a/aegilib/include/aegilib/aegilib.h b/aegilib/include/aegilib/aegilib.h index 62b95d9b2..853dd1edd 100644 --- a/aegilib/include/aegilib/aegilib.h +++ b/aegilib/include/aegilib/aegilib.h @@ -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" ////////// diff --git a/aegilib/include/aegilib/colour.h b/aegilib/include/aegilib/colour.h new file mode 100644 index 000000000..dd4db5b11 --- /dev/null +++ b/aegilib/include/aegilib/colour.h @@ -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); + }; + +}; diff --git a/aegilib/include/aegilib/exception.h b/aegilib/include/aegilib/exception.h index 436ecff8a..7b11fe7f4 100644 --- a/aegilib/include/aegilib/exception.h +++ b/aegilib/include/aegilib/exception.h @@ -49,7 +49,8 @@ namespace Aegilib { Section_Already_Exists, Unknown_Format, Parse_Error, - Unsupported_Format_Feature + Unsupported_Format_Feature, + Invalid_Token }; Exception(ExceptionList code); diff --git a/aegilib/include/aegilib/section_entry_dialogue.h b/aegilib/include/aegilib/section_entry_dialogue.h index 5e1a4f529..2a43d021e 100644 --- a/aegilib/include/aegilib/section_entry_dialogue.h +++ b/aegilib/include/aegilib/section_entry_dialogue.h @@ -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(); } }; }; diff --git a/aegilib/include/aegilib/section_entry_style.h b/aegilib/include/aegilib/section_entry_style.h new file mode 100644 index 000000000..dbfb92afc --- /dev/null +++ b/aegilib/include/aegilib/section_entry_style.h @@ -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; } + }; + +}; diff --git a/aegilib/include/aegilib/tokenizer.h b/aegilib/include/aegilib/tokenizer.h new file mode 100644 index 000000000..7bcb4ebdc --- /dev/null +++ b/aegilib/include/aegilib/tokenizer.h @@ -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(); + }; + +}; diff --git a/aegilib/src/colour.cpp b/aegilib/src/colour.cpp new file mode 100644 index 000000000..e916222a6 --- /dev/null +++ b/aegilib/src/colour.cpp @@ -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; + } +} diff --git a/aegilib/src/exception.cpp b/aegilib/src/exception.cpp index 2620b1f1c..3b12f5fe8 100644 --- a/aegilib/src/exception.cpp +++ b/aegilib/src/exception.cpp @@ -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."; } diff --git a/aegilib/src/formats/format_ass.cpp b/aegilib/src/formats/format_ass.cpp index ee91535c5..fe00154b2 100644 --- a/aegilib/src/formats/format_ass.cpp +++ b/aegilib/src/formats/format_ass.cpp @@ -156,7 +156,18 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version) // Styles else if (group == _T("V4+ Styles")) { - // TODO + 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; -} diff --git a/aegilib/src/formats/format_ass.h b/aegilib/src/formats/format_ass.h index 87ef15b28..54931df35 100644 --- a/aegilib/src/formats/format_ass.h +++ b/aegilib/src/formats/format_ass.h @@ -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]; } }; }; diff --git a/aegilib/src/formats/format_ass_dialogue.cpp b/aegilib/src/formats/format_ass_dialogue.cpp new file mode 100644 index 000000000..904798d1e --- /dev/null +++ b/aegilib/src/formats/format_ass_dialogue.cpp @@ -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; +} diff --git a/aegilib/src/formats/format_ass_style.cpp b/aegilib/src/formats/format_ass_style.cpp new file mode 100644 index 000000000..e50393838 --- /dev/null +++ b/aegilib/src/formats/format_ass_style.cpp @@ -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; + } +} diff --git a/aegilib/src/tokenizer.cpp b/aegilib/src/tokenizer.cpp new file mode 100644 index 000000000..4983cb602 --- /dev/null +++ b/aegilib/src/tokenizer.cpp @@ -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 +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; +}