diff --git a/aegilib/aegilib.vcproj b/aegilib/aegilib.vcproj index b526eca75..c62dd0d9b 100644 --- a/aegilib/aegilib.vcproj +++ b/aegilib/aegilib.vcproj @@ -227,6 +227,10 @@ RelativePath=".\include\aegilib\tokenizer.h" > + + @@ -324,6 +328,10 @@ RelativePath=".\src\tokenizer.cpp" > + + (b)) ? (a) : (b)) -#endif -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif -#ifndef MID -#define MID(a,b,c) MIN(MAX((a),(b)),(c)) -#endif \ No newline at end of file +#include "utils.h" diff --git a/aegilib/include/aegilib/section.h b/aegilib/include/aegilib/section.h index 128b7b808..60adaf006 100644 --- a/aegilib/include/aegilib/section.h +++ b/aegilib/include/aegilib/section.h @@ -37,6 +37,7 @@ #include "aegistring.h" #include "section_entry.h" #include +#include namespace Aegilib { @@ -44,14 +45,22 @@ namespace Aegilib { class Section { private: std::list entries; + std::map properties; String name; public: Section(String name); ~Section(); - String GetName() const { return name; } - String SetName(String newName) { name = newName; } + const String& GetName() const { return name; } + String SetName(const String& newName) { name = newName; } + + void SetProperty(const String &key,const String &value); + void UnsetProperty(const String &key); + String GetProperty(const String &key) const; + bool HasProperty(const String &key) const; + size_t PropertyCount() const; + String GetPropertyName(size_t index) const; void AddEntry(SectionEntry *entry); }; diff --git a/aegilib/include/aegilib/utils.h b/aegilib/include/aegilib/utils.h new file mode 100644 index 000000000..9743b0d53 --- /dev/null +++ b/aegilib/include/aegilib/utils.h @@ -0,0 +1,75 @@ +// 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 "aegilib.h" + + +///////////// +// Templates + +// Returns the largest of two values +template +T Max(T a,T b) +{ + if (b < a) return a; + return b; +} + +// Returns the smallest of two values +template +T Min(T a,T b) +{ + if (a < b) return a; + return b; +} + +// Returns b, but limiting it to the interval [a,c] +template +T Mid(T a,T b,T c) +{ + return Min(Max(a,b),c); +} + + +//////////////////// +// Helper functions +namespace Aegilib { + + // Convert a string to an integer + int StringToInt(const String &str); + +}; diff --git a/aegilib/src/colour.cpp b/aegilib/src/colour.cpp index e916222a6..640e1db60 100644 --- a/aegilib/src/colour.cpp +++ b/aegilib/src/colour.cpp @@ -62,10 +62,10 @@ Colour::Colour (int red,int green,int blue,int 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); } +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); } ////////////// diff --git a/aegilib/src/formats/format_ass.cpp b/aegilib/src/formats/format_ass.cpp index ff3605b54..05bda504f 100644 --- a/aegilib/src/formats/format_ass.cpp +++ b/aegilib/src/formats/format_ass.cpp @@ -108,20 +108,29 @@ void FormatHandlerASS::Load(wxInputStream &file,const String encoding) if (cur[0] == L'[') continue; // Create and insert line - SectionEntry *entry = MakeEntry(cur,curGroup,version); + SectionEntry *entry = MakeEntry(cur,section,version); if (entry) section->AddEntry(entry); } // Debug - cout << "\nFinished reading file with version=" << version << ".\n\n"; + cout << "\nFinished reading file with version=" << version << ".\n"; + cout << "Dumping properties:\n"; + section = model.GetSection(_T("Script Info")); + size_t n = section->PropertyCount(); + for (size_t i=0;iGetPropertyName(i); + cout << name.mb_str(wxConvUTF8) << "=" << section->GetProperty(name).mb_str(wxConvUTF8) << endl; + } + cout << "Done.\n" << endl; } /////////////// // Create line -SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version) +SectionEntry *FormatHandlerASS::MakeEntry(const String &data,Section *section,int version) { // Variables + const String group = section->GetName(); SectionEntry *final = NULL; // Attachments @@ -143,8 +152,7 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version) // Format lines else if (data.Left(7) == _T("Format:")) { - // TODO - //entry = new AssEntry(_T("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text")); + section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false)); } // Garbage @@ -164,8 +172,7 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version) 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")); + section->SetProperty(_T("Format"),data.Mid(7).Trim(true).Trim(false)); } } @@ -174,7 +181,15 @@ SectionEntry *FormatHandlerASS::MakeEntry(String data,String group,int version) // Discard comments if (data.Left(1) == _T(";")) return NULL; - // TODO + // Parse property + size_t pos = data.Find(_T(':')); + if (pos == wxNOT_FOUND) return NULL; + wxString key = data.Left(pos).Trim(true).Trim(false); + wxString value = data.Mid(pos+1).Trim(true).Trim(false); + + // Insert property + section->SetProperty(key,value); + return NULL; } // Return entry diff --git a/aegilib/src/formats/format_ass.h b/aegilib/src/formats/format_ass.h index a27ad0939..09e98e9fe 100644 --- a/aegilib/src/formats/format_ass.h +++ b/aegilib/src/formats/format_ass.h @@ -48,7 +48,7 @@ namespace Aegilib { // Advanced Substation Alpha format handler class FormatHandlerASS : public FormatHandler { private: - SectionEntry *MakeEntry(String data,String group,int version); + SectionEntry *MakeEntry(const String &data,Section *section,int version); void ProcessGroup(String cur,String &curGroup,int &version); Model &model; diff --git a/aegilib/src/formats/format_ass_dialogue.cpp b/aegilib/src/formats/format_ass_dialogue.cpp index c07f80321..476ec2519 100644 --- a/aegilib/src/formats/format_ass_dialogue.cpp +++ b/aegilib/src/formats/format_ass_dialogue.cpp @@ -35,6 +35,7 @@ #include "format_ass.h" #include "tokenizer.h" +#include "utils.h" using namespace Aegilib; @@ -90,9 +91,7 @@ bool DialogueASS::Parse(wxString rawData, int version) // Not SSA, so read layer number else { if (version == 0) version = 1; // Only do it for SSA, not ASS2 - long templ; - temp.ToLong(&templ); - layer = templ; + layer = StringToInt(temp); } // Get times @@ -105,29 +104,25 @@ bool DialogueASS::Parse(wxString rawData, int version) // Get margins for (int i=0;i<3;i++) margin[i] = tkn.GetInt(); + margin[3] = margin[2]; + + // Read next string, which is either bottom margin or effect + temp = tkn.GetString(true); // 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; + if (temp.IsNumber()) { + // Got margin + margin[3] = StringToInt(temp); + + // Read effect + temp = tkn.GetString(true); } + else version = 1; } // Get effect - if (!rollBack) temp = tkn.GetString(); effect = temp; - effect.Trim(true); - effect.Trim(false); // Get text text = rawData.Mid(pos+tkn.GetPosition()); diff --git a/aegilib/src/section.cpp b/aegilib/src/section.cpp index eda6f86fb..1e1655733 100644 --- a/aegilib/src/section.cpp +++ b/aegilib/src/section.cpp @@ -59,3 +59,58 @@ void Section::AddEntry(SectionEntry *entry) { entries.push_back(entry); } + + +////////////////// +// Set a property +void Section::SetProperty(const String &key,const String &value) +{ + properties[key] = value; +} + + +////////////////////// +// Removes a property +void Section::UnsetProperty(const String &key) +{ + std::map::iterator iter = properties.find(key); + if (iter != properties.end()) properties.erase(iter); +} + + +////////////////////////// +// Get a property's value +String Section::GetProperty(const String &key) const +{ + std::map::const_iterator iter = properties.find(key); + if (iter != properties.end()) return iter->second; + else return L""; +} + + +/////////////////////////////// +// Checks if it has a property +bool Section::HasProperty(const String &key) const +{ + return properties.find(key) != properties.end(); +} + + +////////////////////// +// Get property count +size_t Section::PropertyCount() const +{ + return properties.size(); +} + + +/////////////////////////////////// +// Get name of a property by index +String Section::GetPropertyName(size_t index) const +{ + std::map::const_iterator iter=properties.begin(); + for (size_t i=0 ; iter!=properties.end() ; iter++,i++) { + if (i == index) return iter->first; + } + return L""; +} diff --git a/aegilib/src/time.cpp b/aegilib/src/time.cpp index 7cb0c3f4a..53bb59ec5 100644 --- a/aegilib/src/time.cpp +++ b/aegilib/src/time.cpp @@ -42,8 +42,8 @@ using namespace Aegilib; String Time::GetString(int ms_precision,int h_precision) { // Enforce sanity - ms_precision = MID(0,ms_precision,3); - h_precision = MID(0,h_precision,2); + ms_precision = Mid(0,ms_precision,3); + h_precision = Mid(0,h_precision,2); // Generate values int _ms = ms; diff --git a/aegilib/src/utils.cpp b/aegilib/src/utils.cpp new file mode 100644 index 000000000..e6838508b --- /dev/null +++ b/aegilib/src/utils.cpp @@ -0,0 +1,49 @@ +// 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 "utils.h" +using namespace Aegilib; + + +////////////////////////////////// +// Convert a string to an integer +int Aegilib::StringToInt(const String &str) +{ + if (!str.IsNumber()) return 0; + long temp; + str.ToLong(&temp); + return (int) temp; +}