From e2f8e6961298ee3275afcb28e3a00d206111320a Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 24 Jun 2010 01:24:43 +0000 Subject: [PATCH] Beat some semblance of sanity into ass_override and related files. Fixes a pile of crashes when tags are missing expected parameters. Originally committed to SVN as r4581. --- aegisub/src/ass_dialogue.cpp | 182 ++----- aegisub/src/ass_dialogue.h | 109 ++-- aegisub/src/ass_file.cpp | 4 +- aegisub/src/ass_karaoke.cpp | 2 +- aegisub/src/ass_override.cpp | 839 ++++++++++-------------------- aegisub/src/ass_override.h | 128 ++--- aegisub/src/auto4_lua_assfile.cpp | 2 +- aegisub/src/subs_edit_box.cpp | 4 +- aegisub/src/utils.h | 12 + aegisub/src/variable_data.h | 3 + 10 files changed, 413 insertions(+), 872 deletions(-) diff --git a/aegisub/src/ass_dialogue.cpp b/aegisub/src/ass_dialogue.cpp index 504ce9fbd..ce848710d 100644 --- a/aegisub/src/ass_dialogue.cpp +++ b/aegisub/src/ass_dialogue.cpp @@ -47,7 +47,6 @@ #include "utils.h" #include "vfr.h" -/// @brief Constructs AssDialogue AssDialogue::AssDialogue() : Comment(false) , Layer(0) @@ -109,29 +108,21 @@ AssDialogue::AssDialogue(wxString _data,int version) } } -/// @brief Destructor AssDialogue::~AssDialogue () { Clear(); } -/// @brief Clear void AssDialogue::Clear () { ClearBlocks(); } -/// @brief Clear blocks void AssDialogue::ClearBlocks() { - using std::vector; - for (vector::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) { + for (std::vector::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) { delete *cur; } Blocks.clear(); } -/// @brief Parse ASS Data -/// @param rawData -/// @param version -/// @return bool AssDialogue::Parse(wxString rawData, int version) { size_t pos = 0; wxString temp; @@ -224,92 +215,51 @@ bool AssDialogue::Parse(wxString rawData, int version) { return true; } -/// @brief Make data -/// @return -wxString AssDialogue::MakeData() { - // Prepare - static wxString final = _T(""); +wxString AssDialogue::GetData(bool ssa) { + wxString final; - // Write all final - if (Comment) final = _T("Comment: "); - else final = _T("Dialogue: "); + if (Comment) final = L"Comment: "; + else final = L"Dialogue: "; - final += wxString::Format(_T("%01i"),Layer); - final += _T(","); + if (ssa) final += L"Marked=0,"; - final += Start.GetASSFormated() + _T(","); - final += End.GetASSFormated() + _T(","); + final += wxString::Format(L"%01i",Layer); + final += L","; - Style.Replace(_T(","),_T(";")); - Actor.Replace(_T(","),_T(";")); - final += Style + _T(","); - final += Actor + _T(","); + final += Start.GetASSFormated() + L","; + final += End.GetASSFormated() + L","; + + Style.Replace(L",",L";"); + Actor.Replace(L",",L";"); + final += Style + L","; + final += Actor + L","; final += GetMarginString(0); - final += _T(","); + final += L","; final += GetMarginString(1); - final += _T(","); + final += L","; final += GetMarginString(2); - final += _T(","); + final += L","; - Effect.Replace(_T(","),_T(";")); - final += Effect + _T(","); + Effect.Replace(L",",L";"); + final += Effect + L","; final += Text; // Make sure that final has no line breaks - final.Replace(_T("\n"),_T("")); - final.Replace(_T("\r"),_T("")); + final.Replace(L"\n",""); + final.Replace(L"\r",""); - // Return final return final; } -/// @brief Get entry data -/// @return const wxString AssDialogue::GetEntryData() { - return MakeData(); + return GetData(false); } -/// @brief Set entry data -/// @param newData -void AssDialogue::SetEntryData(wxString newData) { -} - -/// @brief Get SSA version of Dialogue -/// @return wxString AssDialogue::GetSSAText () { - // Prepare - wxString work = _T(""); - - // Write all work - if (Comment) work += _T("Comment: "); - else work += _T("Dialogue: "); - - work += _T("Marked=0,"); - - work += Start.GetASSFormated() + _T(","); - work += End.GetASSFormated() + _T(","); - - Style.Replace(_T(","),_T(";")); - Actor.Replace(_T(","),_T(";")); - work += Style + _T(","); - work += Actor + _T(","); - - work += GetMarginString(0); - work += _T(","); - work += GetMarginString(1); - work += _T(","); - work += GetMarginString(2); - work += _T(","); - - Effect.Replace(_T(","),_T(";")); - work += Effect + _T(","); - work += Text; - - return work; + return GetData(true); } -/// @brief Yea, I convert to ASS tags, then parse that. So sue me. -------------- Parse SRT tags void AssDialogue::ParseSRTTags () { // Search and replace size_t total = 0; @@ -350,7 +300,7 @@ void AssDialogue::ParseSRTTags () { // Open tag if (isOpen) { - wxString replaced = _T(""); + wxString replaced; // Color tag if ((pos = work.find(_T("COLOR=\""),start)) != wxString::npos) { @@ -441,15 +391,11 @@ void AssDialogue::ParseSRTTags () { Text.Replace(_T("}{"),_T("")); } -/// @brief Parse ASS tags void AssDialogue::ParseASSTags () { - // Clear blocks ClearBlocks(); - // Is drawing? int drawingLevel = 0; - // Loop through const size_t len = Text.size(); size_t cur = 0; size_t end = 0; @@ -472,7 +418,6 @@ void AssDialogue::ParseASSTags () { AssDialogueBlockPlain *block = new AssDialogueBlockPlain; block->text = work; Blocks.push_back(block); - } else { @@ -487,9 +432,8 @@ void AssDialogue::ParseASSTags () { // Look for \p in block std::vector::iterator curTag; for (curTag = block->Tags.begin();curTag != block->Tags.end();curTag++) { - AssOverrideTag *tag = *curTag; - if (tag->Name == _T("\\p")) { - drawingLevel = tag->Params.at(0)->Get(); + if ((*curTag)->Name == L"\\p") { + drawingLevel = (*curTag)->Params[0]->Get(0); } } } @@ -535,16 +479,11 @@ void AssDialogue::ParseASSTags () { } } -/// @brief Strip tags void AssDialogue::StripTags () { - static wxRegEx reg(_T("\\{[^\\{]*\\}"),wxRE_ADVANCED); - reg.Replace(&Text,_T("")); + Text = GetStrippedText(); } -/// @brief Strip a specific tag -/// @param tagName void AssDialogue::StripTag (wxString tagName) { - // Parse using std::list; using std::vector; ParseASSTags(); @@ -556,7 +495,7 @@ void AssDialogue::StripTag (wxString tagName) { AssDialogueBlockOverride *over = dynamic_cast(*cur); wxString temp; for (size_t i=0;iTags.size();i++) { - if (over->Tags[i]->Name != tagName) temp += over->Tags[i]->ToString(); + if (over->Tags[i]->Name != tagName) temp += *over->Tags[i]; } // Insert @@ -565,14 +504,11 @@ void AssDialogue::StripTag (wxString tagName) { else final += (*cur)->GetText(); } - // Update ClearBlocks(); Text = final; } -/// @brief TODO: Improve this code ------------------- Convert tags to SRT void AssDialogue::ConvertTagsToSRT () { - // Setup using std::list; using std::vector; AssDialogueBlockOverride* curBlock; @@ -669,11 +605,10 @@ void AssDialogue::ConvertTagsToSRT () { ClearBlocks(); } -/// @brief Updates text from tags void AssDialogue::UpdateText () { - using std::vector; - Text = _T(""); - for (vector::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) { + if (Blocks.empty()) return; + Text.clear(); + for (std::vector::iterator cur=Blocks.begin();cur!=Blocks.end();cur++) { if ((*cur)->GetType() == BLOCK_OVERRIDE) { Text += _T("{"); Text += (*cur)->GetText(); @@ -683,10 +618,9 @@ void AssDialogue::UpdateText () { } } -/// @brief Sets margin from a string -/// @param origvalue -/// @param which void AssDialogue::SetMarginString(const wxString origvalue,int which) { + if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError(); + // Make it numeric wxString strvalue = origvalue; if (!strvalue.IsNumber()) { @@ -707,14 +641,9 @@ void AssDialogue::SetMarginString(const wxString origvalue,int which) { if (value > 9999) value = 9999; // Assign - if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError(); Margin[which] = value; } -/// @brief Gets string for margin -/// @param which -/// @param pad -/// @return wxString AssDialogue::GetMarginString(int which,bool pad) { if (which < 0 || which >= 4) throw Aegisub::InvalidMarginIdError(); int value = Margin[which]; @@ -735,9 +664,6 @@ void AssDialogue::ProcessParameters(AssDialogueBlockOverride::ProcessParametersC //ClearBlocks(); } -/// @brief Checks if two lines collide -/// @param target -/// @return bool AssDialogue::CollidesWith(AssDialogue *target) { if (!target) return false; int a = Start.GetMS(); @@ -747,49 +673,20 @@ bool AssDialogue::CollidesWith(AssDialogue *target) { return ((a < c) ? (c < b) : (a < d)); } -/// @brief Return just the text without any overrides -/// @return wxString AssDialogue::GetStrippedText() const { - wxString justtext = wxString(_T("")); - bool inCode = false; - - for (size_t charindex = 0; charindex != Text.Len(); charindex++) { - if (Text[charindex] == '{') inCode = true; - else if (Text[charindex] == '}') inCode = false; - else if (!inCode) justtext = justtext + Text[charindex]; - } - return justtext; + static wxRegEx reg(_T("\\{[^\\{]*\\}"),wxRE_ADVANCED); + wxString txt(Text); + reg.Replace(&txt,_T("")); + return txt; } -/// @brief Clone -/// @return AssEntry *AssDialogue::Clone() const { return new AssDialogue(*this); } -/// @brief Constructor AssDialogueBlock -AssDialogueBlock::AssDialogueBlock () { -} - -/// @brief Destructor -AssDialogueBlock::~AssDialogueBlock () { -} - -/// @brief Constructor AssDialogueBlockPlain -AssDialogueBlockPlain::AssDialogueBlockPlain () { -} - -/// @brief Constructor AssDialogueBlockDrawing -AssDialogueBlockDrawing::AssDialogueBlockDrawing () { -} - -/// @brief Multiply coordinates -/// @param mx -/// @param my -/// @param x -/// @param y void AssDialogueBlockDrawing::TransformCoords(int mx,int my,double x,double y) { // HACK: Implement a proper parser ffs!! + // Could use Spline but it'd be slower and this seems to work fine wxStringTokenizer tkn(GetText(),_T(" "),wxTOKEN_DEFAULT); wxString cur; wxString final; @@ -825,4 +722,3 @@ void AssDialogueBlockDrawing::TransformCoords(int mx,int my,double x,double y) { final = final.Left(final.Length()-1); text = final; } - diff --git a/aegisub/src/ass_dialogue.h b/aegisub/src/ass_dialogue.h index 9ac1e8fcb..ac11ba876 100644 --- a/aegisub/src/ass_dialogue.h +++ b/aegisub/src/ass_dialogue.h @@ -34,10 +34,6 @@ /// @ingroup subs_storage /// - -//////////// -// Includes - #ifndef AGI_PRE #include #endif @@ -45,33 +41,15 @@ #include "ass_entry.h" #include "ass_time.h" - -////////////// -// Prototypes -class AssOverrideParameter; -class AssOverrideTag; -class AssDialogueBlockPlain; -class AssDialogueBlockOverride; -class AssDialogueBlockDrawing; - - - -/// DOCME enum ASS_BlockType { - - /// DOCME BLOCK_BASE, - - /// DOCME BLOCK_PLAIN, - - /// DOCME BLOCK_OVERRIDE, - - /// DOCME BLOCK_DRAWING }; +class AssOverrideParameter; +class AssOverrideTag; /// DOCME /// @class AssDialogueBlock @@ -97,15 +75,14 @@ enum ASS_BlockType { /// @endverbatim class AssDialogueBlock { public: - /// DOCME wxString text; /// DOCME AssDialogue *parent; - AssDialogueBlock(); - virtual ~AssDialogueBlock(); + AssDialogueBlock() { } + virtual ~AssDialogueBlock() { } virtual ASS_BlockType GetType() = 0; @@ -125,12 +102,8 @@ public: /// DOCME class AssDialogueBlockPlain : public AssDialogueBlock { public: - - /// @brief DOCME - /// @return - /// ASS_BlockType GetType() { return BLOCK_PLAIN; } - AssDialogueBlockPlain(); + AssDialogueBlockPlain() { } }; @@ -142,16 +115,11 @@ public: /// DOCME class AssDialogueBlockDrawing : public AssDialogueBlock { public: - /// DOCME int Scale; - - /// @brief DOCME - /// @return - /// ASS_BlockType GetType() { return BLOCK_DRAWING; } - AssDialogueBlockDrawing(); + AssDialogueBlockDrawing() { } void TransformCoords(int trans_x,int trans_y,double mult_x,double mult_y); }; @@ -164,7 +132,7 @@ public: /// DOCME class AssDialogueBlockOverride : public AssDialogueBlock { public: - AssDialogueBlockOverride(); + AssDialogueBlockOverride() { } ~AssDialogueBlockOverride(); /// DOCME @@ -195,15 +163,12 @@ public: /// /// DOCME class AssDialogue : public AssEntry { -private: - wxString MakeData(); - + wxString GetData(bool ssa); public: /// Contains information about each block of text std::vector Blocks; - /// Is this a comment line? bool Comment; /// Layer number @@ -223,36 +188,54 @@ public: /// Raw text data wxString Text; - - /// @brief DOCME - /// @return - /// ASS_EntryType GetType() { return ENTRY_DIALOGUE; } - bool Parse(wxString data,int version=1); // Parses raw ASS data into everything else - void ParseASSTags(); // Parses text to generate block information (doesn't update data) - void ParseSRTTags(); // Converts tags to ass format and calls ParseASSTags+UpdateData - void ClearBlocks(); // Clear all blocks, ALWAYS call this after you're done processing tags + /// @brief Parse raw ASS data into everything else + /// @param data ASS line + /// @param version ASS version to try first (4, 4+, ASS2) + /// @return Did it successfully parse? + bool Parse(wxString data,int version=1); + /// Parse text as ASS to generate block information + void ParseASSTags(); + /// Parse text as SRT to generate block information + void ParseSRTTags(); + /// Clear all blocks, ALWAYS call this after you're done processing tags + void ClearBlocks(); /// @brief Process parameters via callback - /// @param callback The callback function to call per tag paramer + /// @param callback The callback function to call per tag parameter /// @param userData User data to pass to callback function - void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL); // Callback to process parameters - void ConvertTagsToSRT(); // Converts tags to SRT format - void StripTags(); // Strips all tags from the text - void StripTag(wxString tagName);// Strips a specific tag from the text - wxString GetStrippedText() const; // Gets text without tags + void ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData=NULL); + /// Convert ASS tags to SRT tags + void ConvertTagsToSRT(); + /// Strip all ASS tags from the text + void StripTags(); + /// Strip a specific ASS tag from the text + void StripTag(wxString tagName); + /// Get text without tags + wxString GetStrippedText() const; - void UpdateText(); // Generates text from the override tags + /// If blocks have been parsed, update the text from their current value + void UpdateText(); const wxString GetEntryData(); - void SetEntryData(wxString newData); - void Clear(); // Wipes all data + /// Do nothing + void SetEntryData(wxString) { } + /// Synonym for ClearBlocks + void Clear(); - void SetMarginString(const wxString value,int which); // Set string to a margin value (0 = left, 1 = right, 2 = vertical/top, 3 = bottom) - wxString GetMarginString(int which,bool pad=true); // Returns the string of a margin value (0 = left, 1 = right, 2 = vertical/top, 3 = bottom) + /// @brief Set a margin + /// @param value New value of the margin + /// @param which 0 = left, 1 = right, 2 = vertical/top, 3 = bottom + void SetMarginString(const wxString value,int which); + /// @brief Get a margin + /// @param which 0 = left, 1 = right, 2 = vertical/top, 3 = bottom + /// @param pad Pad the number to four digits + wxString GetMarginString(int which,bool pad=true); + /// Get the line as SSA rather than ASS wxString GetSSAText(); - bool CollidesWith(AssDialogue *target); // Checks if two lines collide + /// Does this line collide with the passed line? + bool CollidesWith(AssDialogue *target); AssEntry *Clone() const; diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index c912405be..7ab0cae88 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -64,8 +64,8 @@ /// @brief AssFile constructor AssFile::AssFile () { - AssOverrideTagProto::LoadProtos(); - Clear(); + loaded = false; + Modified = false; } /// @brief AssFile destructor diff --git a/aegisub/src/ass_karaoke.cpp b/aegisub/src/ass_karaoke.cpp index 6c604bf4d..d04a735e2 100644 --- a/aegisub/src/ass_karaoke.cpp +++ b/aegisub/src/ass_karaoke.cpp @@ -110,7 +110,7 @@ void ParseAssKaraokeTags(const AssDialogue *line, AssKaraokeVector &syls) syl.unstripped_text += _T("{"); brackets_open = true; } - syl.unstripped_text += tag->ToString(); + syl.unstripped_text += *tag; } } diff --git a/aegisub/src/ass_override.cpp b/aegisub/src/ass_override.cpp index 79f193b72..d95d1899f 100644 --- a/aegisub/src/ass_override.cpp +++ b/aegisub/src/ass_override.cpp @@ -1,4 +1,5 @@ // Copyright (c) 2005, Rodrigo Braz Monteiro +// Copyright (c) 2010, Thomas Goyne // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -45,114 +46,72 @@ #include "ass_dialogue.h" #include "ass_override.h" +#include "utils.h" -/// @brief Constructor -AssOverrideParameter::AssOverrideParameter () { - classification = PARCLASS_NORMAL; - ommited = false; +AssOverrideParameter::AssOverrideParameter() +: classification(PARCLASS_NORMAL) +, omitted(false) +{ } -/// @brief Destructor -AssOverrideParameter::~AssOverrideParameter () { +AssOverrideParameter::AssOverrideParameter(const AssOverrideParameter ¶m) +: VariableData(param) +, classification(param.classification) +, omitted(param.omitted) +{ +} + +void AssOverrideParameter::operator=(const AssOverrideParameter ¶m) { DeleteValue(); + new(this) AssOverrideParameter(param); } -/// @brief Copy -/// @param param -/// -void AssOverrideParameter::CopyFrom (const AssOverrideParameter ¶m) { - *static_cast(this) = static_cast(param); - classification = param.classification; - ommited = param.ommited; +// From ass_dialogue.h +AssDialogueBlockOverride::~AssDialogueBlockOverride() { + delete_clear(Tags); } -/// @brief DOCME -/// @param param -/// -void AssOverrideParameter::operator= (const AssOverrideParameter ¶m) { - CopyFrom(param); -} +void AssDialogueBlockOverride::ParseTags() { + delete_clear(Tags); -/// @brief Constructor -AssDialogueBlockOverride::AssDialogueBlockOverride () { -} - -/// @brief Destructor -AssDialogueBlockOverride::~AssDialogueBlockOverride () { - for (size_t i=0;i text.Freq(_T(')'))) { - text += _T(")"); - } - - // Initialize tokenizer - wxStringTokenizer tkn(text,_T("\\"),wxTOKEN_RET_EMPTY_ALL); + wxStringTokenizer tkn(text, L"\\", wxTOKEN_STRTOK); wxString curTag; - if (text.StartsWith(_T("\\"))) curTag = _T("\\"); + if (text.StartsWith(L"\\")) curTag = L"\\"; while (tkn.HasMoreTokens()) { - //curTag will always start with a backslash after first loop - see end of loop curTag += tkn.GetNextToken(); - if (curTag == _T("\\")) continue; - // Check for parenthesis matching - while (curTag.Freq(_T('(')) > curTag.Freq(_T(')'))) { - if (!tkn.HasMoreTokens()) { - wxLogWarning(_T("Unmatched parenthesis! Line contents: ") + parent->Text); - break; - } - curTag << _T("\\") << tkn.GetNextToken(); + // Check for parenthesis matching for \t + while (curTag.Freq(L'(') > curTag.Freq(L')') && tkn.HasMoreTokens()) { + curTag << L"\\" << tkn.GetNextToken(); } - AssOverrideTag *newTag = new AssOverrideTag; - newTag->SetText(curTag); - Tags.push_back(newTag); + Tags.push_back(new AssOverrideTag(curTag)); - curTag = _T("\\"); + curTag = L"\\"; } } void AssDialogueBlockOverride::AddTag(wxString const& tag) { - AssOverrideTag *newTag = new AssOverrideTag; - newTag->SetText(tag); - Tags.push_back(newTag); + Tags.push_back(new AssOverrideTag(tag)); } -/// @brief Get Text representation -/// @return -/// -wxString AssDialogueBlockOverride::GetText () { - text = _T(""); +wxString AssDialogueBlockOverride::GetText() { + text.clear(); for (std::vector::iterator cur=Tags.begin();cur!=Tags.end();cur++) { - text += (*cur)->ToString(); + text += **cur; } return text; } void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData) { for (std::vector::iterator cur=Tags.begin();cur!=Tags.end();cur++) { - int n = 0; AssOverrideTag *curTag = *cur; // Find parameters - for (std::vector::iterator curParam=curTag->Params.begin();curParam!=curTag->Params.end();curParam++) { - AssOverrideParameter *curPar = *curParam; + for (unsigned n = 0; n < curTag->Params.size(); n++) { + AssOverrideParameter *curPar = curTag->Params[n]; - if (curPar->GetType() != VARDATA_NONE && curPar->ommited == false) { - // Do callback + if (curPar->GetType() != VARDATA_NONE && !curPar->omitted) { (*callback)(curTag->Name,n,curPar,userData); // Go recursive if it's a block parameter @@ -160,45 +119,28 @@ void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::Proce curPar->Get()->ProcessParameters(callback,userData); } } - - n++; } } } -/// @brief Constructor -/// @param _type -/// @param opt -/// @param classi -/// -AssOverrideParamProto::AssOverrideParamProto (VariableDataType _type,int opt,ASS_ParameterClass classi) { - type = _type; - optional = opt; - classification = classi; +AssOverrideParamProto::AssOverrideParamProto(VariableDataType type,int opt,ASS_ParameterClass classi) +: type(type) +, optional(opt) +, classification(classi) +{ } -/// @brief Destructor -AssOverrideParamProto::~AssOverrideParamProto() { +void AssOverrideTagProto::AddParam(VariableDataType type, ASS_ParameterClass classi, int opt) { + params.push_back(AssOverrideParamProto(type, opt, classi)); +} +void AssOverrideTagProto::Set(wxString newName, VariableDataType type, ASS_ParameterClass classi, int opt) { + name = newName; + params.push_back(AssOverrideParamProto(type, opt, classi)); } -/// DOCME -std::vector AssOverrideTagProto::proto; - -/// DOCME -bool AssOverrideTagProto::loaded = false; - -/// @brief Constructor -AssOverrideTagProto::AssOverrideTagProto() { -} - -/// @brief Destructor -AssOverrideTagProto::~AssOverrideTagProto() { -} - -/// @brief Load prototypes -/// @return -/// -void AssOverrideTagProto::LoadProtos () { +static std::vector proto; +static void load_protos() { + static bool loaded = false; if (loaded) return; loaded = true; @@ -207,341 +149,149 @@ void AssOverrideTagProto::LoadProtos () { // Longer tag names must appear before shorter tag names - // \alpha - proto[i].name = _T("\\alpha"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT)); - - // \bord - i++; - proto[i].name = _T("\\bord"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \xbord - i++; - proto[i].name = _T("\\xbord"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \ybord - i++; - proto[i].name = _T("\\ybord"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \shad - i++; - proto[i].name = _T("\\shad"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \xshad - i++; - proto[i].name = _T("\\xshad"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \yshad - i++; - proto[i].name = _T("\\yshad"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - + proto[0].Set(L"\\alpha", VARDATA_TEXT); // \alpha + proto[++i].Set(L"\\bord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \bord + proto[++i].Set(L"\\xbord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \xbord + proto[++i].Set(L"\\ybord", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \ybord + proto[++i].Set(L"\\shad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \shad + proto[++i].Set(L"\\xshad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \xshad + proto[++i].Set(L"\\yshad", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \yshad + // \fade(,,,,,,) i++; - proto[i].name = _T("\\fade"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START)); + proto[i].name = L"\\fade"; + proto[i].AddParam(VARDATA_INT); + proto[i].AddParam(VARDATA_INT); + proto[i].AddParam(VARDATA_INT); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); // \move(,,,[,,]) i++; - proto[i].name = _T("\\move"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START)); + proto[i].name = L"\\move"; + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y); + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); // If these are rearranged, keep rect clip and vector clip adjacent in this order // \clip(,,,) i++; - proto[i].name = _T("\\clip"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto[i].name = L"\\clip"; + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); // \clip([,]) i++; - proto[i].name = _T("\\clip"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING)); + proto[i].name = L"\\clip"; + proto[i].AddParam(VARDATA_INT,PARCLASS_NORMAL,OPTIONAL_2); + proto[i].AddParam(VARDATA_TEXT,PARCLASS_DRAWING); // \iclip(,,,) i++; - proto[i].name = _T("\\iclip"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto[i].name = L"\\iclip"; + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); // \iclip([,]) i++; - proto[i].name = _T("\\iclip"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING)); - - // \fscx - i++; - proto[i].name = _T("\\fscx"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_RELATIVE_SIZE_X)); - - // \fscy - i++; - proto[i].name = _T("\\fscy"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_RELATIVE_SIZE_Y)); + proto[i].name = L"\\iclip"; + proto[i].AddParam(VARDATA_INT,PARCLASS_NORMAL,OPTIONAL_2); + proto[i].AddParam(VARDATA_TEXT,PARCLASS_DRAWING); + proto[++i].Set(L"\\fscx", VARDATA_FLOAT,PARCLASS_RELATIVE_SIZE_X); // \fscx + proto[++i].Set(L"\\fscy", VARDATA_FLOAT,PARCLASS_RELATIVE_SIZE_Y); // \fscy // \pos(,) i++; - proto[i].name = _T("\\pos"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto[i].name = L"\\pos"; + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_FLOAT,PARCLASS_ABSOLUTE_POS_Y); // \org(,) i++; - proto[i].name = _T("\\org"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - - // \pbo - i++; - proto[i].name = _T("\\pbo"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto[i].name = L"\\org"; + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_X); + proto[i].AddParam(VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); + proto[++i].Set(L"\\pbo", VARDATA_INT,PARCLASS_ABSOLUTE_POS_Y); // \pbo // \fad(,) i++; - proto[i].name = _T("\\fad"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_START)); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_RELATIVE_TIME_END)); + proto[i].name = L"\\fad"; + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); + proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_END); - // \fsp - i++; - proto[i].name = _T("\\fsp"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \frx - i++; - proto[i].name = _T("\\frx"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fry - i++; - proto[i].name = _T("\\fry"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \frz - i++; - proto[i].name = _T("\\frz"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fr - i++; - proto[i].name = _T("\\fr"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fax - i++; - proto[i].name = _T("\\fax"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fay - i++; - proto[i].name = _T("\\fay"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \1c&H& - i++; - proto[i].name = _T("\\1c"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \2c&H& - i++; - proto[i].name = _T("\\2c"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \3c&H& - i++; - proto[i].name = _T("\\3c"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \4c&H& - i++; - proto[i].name = _T("\\4c"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \1a&H& - i++; - proto[i].name = _T("\\1a"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \2a&H& - i++; - proto[i].name = _T("\\2a"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \3a&H& - i++; - proto[i].name = _T("\\3a"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \4a&H& - i++; - proto[i].name = _T("\\4a"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fe - i++; - proto[i].name = _T("\\fe"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \ko - i++; - proto[i].name = _T("\\ko"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE)); - - // \kf - i++; - proto[i].name = _T("\\kf"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE)); - - // \be - i++; - proto[i].name = _T("\\be"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \blur - i++; - proto[i].name = _T("\\blur"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fn - i++; - proto[i].name = _T("\\fn"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fs+ - i++; - proto[i].name = _T("\\fs+"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fs- - i++; - proto[i].name = _T("\\fs-"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \fs - i++; - proto[i].name = _T("\\fs"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); - - // \an - i++; - proto[i].name = _T("\\an"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \c&H& - i++; - proto[i].name = _T("\\c"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \b<0/1/weight> - i++; - proto[i].name = _T("\\b"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_1,PARCLASS_NORMAL)); - proto[i].params.back().defaultValue.Set(false); - - // \i<0/1> - i++; - proto[i].name = _T("\\i"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL)); - proto[i].params.back().defaultValue.Set(false); - - // \u<0/1> - i++; - proto[i].name = _T("\\u"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL)); - proto[i].params.back().defaultValue.Set(false); - - // \s<0/1> - i++; - proto[i].name = _T("\\s"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_BOOL,OPTIONAL_1,PARCLASS_NORMAL)); - proto[i].params.back().defaultValue.Set(false); - - // \a - i++; - proto[i].name = _T("\\a"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \k - i++; - proto[i].name = _T("\\k"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE)); - - // \K - i++; - proto[i].name = _T("\\K"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE)); - - // \q<0-3> - i++; - proto[i].name = _T("\\q"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \p - i++; - proto[i].name = _T("\\p"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); - - // \r[] - i++; - proto[i].name = _T("\\r"); - proto[i].params.push_back(AssOverrideParamProto(VARDATA_TEXT,OPTIONAL_1,PARCLASS_NORMAL)); + proto[++i].Set(L"\\fsp", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \fsp + proto[++i].Set(L"\\frx", VARDATA_FLOAT); // \frx + proto[++i].Set(L"\\fry", VARDATA_FLOAT); // \fry + proto[++i].Set(L"\\frz", VARDATA_FLOAT); // \frz + proto[++i].Set(L"\\fr", VARDATA_FLOAT); // \fr + proto[++i].Set(L"\\fax", VARDATA_FLOAT); // \fax + proto[++i].Set(L"\\fay", VARDATA_FLOAT); // \fay + proto[++i].Set(L"\\1c", VARDATA_TEXT); // \1c&H& + proto[++i].Set(L"\\2c", VARDATA_TEXT); // \2c&H& + proto[++i].Set(L"\\3c", VARDATA_TEXT); // \3c&H& + proto[++i].Set(L"\\4c", VARDATA_TEXT); // \4c&H& + proto[++i].Set(L"\\1a", VARDATA_TEXT); // \1a&H& + proto[++i].Set(L"\\2a", VARDATA_TEXT); // \2a&H& + proto[++i].Set(L"\\3a", VARDATA_TEXT); // \3a&H& + proto[++i].Set(L"\\4a", VARDATA_TEXT); // \4a&H& + proto[++i].Set(L"\\fe", VARDATA_TEXT); // \fe + proto[++i].Set(L"\\ko", VARDATA_INT,PARCLASS_KARAOKE); // \ko + proto[++i].Set(L"\\kf", VARDATA_INT,PARCLASS_KARAOKE); // \kf + proto[++i].Set(L"\\be", VARDATA_INT); // \be + proto[++i].Set(L"\\blur", VARDATA_FLOAT); // \blur + proto[++i].Set(L"\\fn", VARDATA_TEXT); // \fn + proto[++i].Set(L"\\fs+", VARDATA_FLOAT); // \fs+ + proto[++i].Set(L"\\fs-", VARDATA_FLOAT); // \fs- + proto[++i].Set(L"\\fs", VARDATA_FLOAT,PARCLASS_ABSOLUTE_SIZE); // \fs + proto[++i].Set(L"\\an", VARDATA_INT); // \an + proto[++i].Set(L"\\c", VARDATA_TEXT); // \c&H& + proto[++i].Set(L"\\b", VARDATA_INT); // \b<0/1/weight> + proto[++i].Set(L"\\i", VARDATA_BOOL); // \i<0/1> + proto[++i].Set(L"\\u", VARDATA_BOOL); // \u<0/1> + proto[++i].Set(L"\\s", VARDATA_BOOL); // \s<0/1> + proto[++i].Set(L"\\a", VARDATA_INT); // \a + proto[++i].Set(L"\\k", VARDATA_INT,PARCLASS_KARAOKE); // \k + proto[++i].Set(L"\\K", VARDATA_INT,PARCLASS_KARAOKE); // \K + proto[++i].Set(L"\\q", VARDATA_INT); // \q<0-3> + proto[++i].Set(L"\\p", VARDATA_INT); // \p + proto[++i].Set(L"\\r", VARDATA_TEXT); // \r[] // \t([,,][,]