// 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 // 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" #include "utils.h" AssOverrideParameter::AssOverrideParameter() : classification(PARCLASS_NORMAL) , omitted(false) { } AssOverrideParameter::AssOverrideParameter(const AssOverrideParameter ¶m) : VariableData(param) , classification(param.classification) , omitted(param.omitted) { } void AssOverrideParameter::operator=(const AssOverrideParameter ¶m) { DeleteValue(); new(this) AssOverrideParameter(param); } // From ass_dialogue.h AssDialogueBlockOverride::~AssDialogueBlockOverride() { delete_clear(Tags); } void AssDialogueBlockOverride::ParseTags() { delete_clear(Tags); wxStringTokenizer tkn(text, L"\\", wxTOKEN_STRTOK); wxString curTag; if (text.StartsWith(L"\\")) curTag = L"\\"; while (tkn.HasMoreTokens()) { curTag += tkn.GetNextToken(); // Check for parenthesis matching for \t while (curTag.Freq(L'(') > curTag.Freq(L')') && tkn.HasMoreTokens()) { curTag << L"\\" << tkn.GetNextToken(); } Tags.push_back(new AssOverrideTag(curTag)); curTag = L"\\"; } } void AssDialogueBlockOverride::AddTag(wxString const& tag) { Tags.push_back(new AssOverrideTag(tag)); } wxString AssDialogueBlockOverride::GetText() { text.clear(); for (std::vector::iterator cur=Tags.begin();cur!=Tags.end();cur++) { text += **cur; } return text; } void AssDialogueBlockOverride::ProcessParameters(AssDialogueBlockOverride::ProcessParametersCallback callback,void *userData) { for (std::vector::iterator cur=Tags.begin();cur!=Tags.end();cur++) { AssOverrideTag *curTag = *cur; // Find parameters for (unsigned n = 0; n < curTag->Params.size(); n++) { AssOverrideParameter *curPar = curTag->Params[n]; if (curPar->GetType() != VARDATA_NONE && !curPar->omitted) { (*callback)(curTag->Name,n,curPar,userData); // Go recursive if it's a block parameter if (curPar->GetType() == VARDATA_BLOCK) { curPar->Get()->ProcessParameters(callback,userData); } } } } } AssOverrideParamProto::AssOverrideParamProto(VariableDataType type,int opt,ASS_ParameterClass classi) : type(type) , optional(opt) , classification(classi) { } 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)); } static std::vector proto; static void load_protos() { static bool loaded = false; if (loaded) return; loaded = true; proto.resize(56); int i = 0; // Longer tag names must appear before shorter tag names 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 = 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 = 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 = 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 = L"\\clip"; proto[i].AddParam(VARDATA_INT,PARCLASS_NORMAL,OPTIONAL_2); proto[i].AddParam(VARDATA_TEXT,PARCLASS_DRAWING); // \iclip(,,,) i++; 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 = 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 = 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 = 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 = L"\\fad"; proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_START); proto[i].AddParam(VARDATA_INT,PARCLASS_RELATIVE_TIME_END); 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([,,][,]