// Copyright (c) 2005, 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 Project http://www.aegisub.org/ // // $Id$ /// @file ass_override.cpp /// @brief Parse and modify ASSA style overrides /// @ingroup subs_storage /// #include "config.h" #ifndef AGI_PRE #include #include #endif #include #include "ass_dialogue.h" #include "ass_override.h" /// @brief Constructor AssOverrideParameter::AssOverrideParameter () { classification = PARCLASS_NORMAL; ommited = false; } /// @brief Destructor AssOverrideParameter::~AssOverrideParameter () { DeleteValue(); } /// @brief Copy /// @param param /// void AssOverrideParameter::CopyFrom (const AssOverrideParameter ¶m) { *static_cast(this) = static_cast(param); classification = param.classification; ommited = param.ommited; } /// @brief DOCME /// @param param /// void AssOverrideParameter::operator= (const AssOverrideParameter ¶m) { CopyFrom(param); } /// @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); wxString curTag; if (text.StartsWith(_T("\\"))) curTag = _T("\\"); 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(); } AssOverrideTag *newTag = new AssOverrideTag; newTag->SetText(curTag); Tags.push_back(newTag); curTag = _T("\\"); } } void AssDialogueBlockOverride::AddTag(wxString const& tag) { AssOverrideTag *newTag = new AssOverrideTag; newTag->SetText(tag); Tags.push_back(newTag); } /// @brief Get Text representation /// @return /// wxString AssDialogueBlockOverride::GetText () { text = _T(""); for (std::vector::iterator cur=Tags.begin();cur!=Tags.end();cur++) { text += (*cur)->ToString(); } 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; if (curPar->GetType() != VARDATA_NONE && curPar->ommited == false) { // Do callback (*callback)(curTag->Name,n,curPar,userData); // Go recursive if it's a block parameter if (curPar->GetType() == VARDATA_BLOCK) { 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; } /// @brief Destructor AssOverrideParamProto::~AssOverrideParamProto() { } /// 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 () { if (loaded) return; loaded = true; proto.resize(56); int i = 0; // 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)); // \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)); // \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)); // 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)); // \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)); // \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)); // \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)); // \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)); // \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)); // \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)); // \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)); // \t([,,][,]