From 50d1b3ed2d2f2152d3d234ff091d4de57e752abb Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 24 Jun 2010 01:23:43 +0000 Subject: [PATCH] Rewrite the ass parsing code in visual_tool.cpp, eliminating a lot of repeated code and making it better at finding the correct values. Originally committed to SVN as r4573. --- aegisub/src/ass_file.cpp | 28 +-- aegisub/src/visual_tool.cpp | 359 ++++++++------------------- aegisub/src/visual_tool_rotatexy.cpp | 7 +- aegisub/src/visual_tool_rotatez.cpp | 4 +- 4 files changed, 117 insertions(+), 281 deletions(-) diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index 1bd3050e0..27eeb8435 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -58,6 +58,7 @@ #include "subtitle_format.h" #include "text_file_reader.h" #include "text_file_writer.h" +#include "utils.h" #include "version.h" #include "vfr.h" @@ -411,14 +412,11 @@ void AssFile::AddLine(wxString data,wxString group,int &version,wxString *outGro return; } -void AssFile::Clear () { - for (entryIter cur=Line.begin();cur != Line.end();cur++) { - delete *cur; - } - Line.clear(); +void AssFile::Clear() { + delete_clear(Line); loaded = false; - filename = _T(""); + filename.clear(); Modified = false; } @@ -756,12 +754,7 @@ bool AssFile::IsModified() { void AssFile::FlagAsModified(wxString desc) { if (!RedoStack.empty()) { - //StackPush(); - //UndoStack.push_back(new AssFile(*UndoStack.back())); - for (std::list::iterator cur=RedoStack.begin();cur!=RedoStack.end();cur++) { - delete *cur; - } - RedoStack.clear(); + delete_clear(RedoStack); } Modified = true; @@ -841,15 +834,8 @@ void AssFile::StackRedo() { } void AssFile::StackClear() { - for (std::list::iterator cur=UndoStack.begin();cur!=UndoStack.end();cur++) { - delete *cur; - } - UndoStack.clear(); - - for (std::list::iterator cur=RedoStack.begin();cur!=RedoStack.end();cur++) { - delete *cur; - } - RedoStack.clear(); + delete_clear(UndoStack); + delete_clear(RedoStack); Popping = false; } diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index 49d079f2a..7c807ce1b 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -410,32 +410,53 @@ void VisualTool::SetEditbox(int lineN) { } } -/// @brief Get position of line -/// @param diag -/// @param x -/// @param y +enum TagFoundType { + TAG_NOT_FOUND = 0, + PRIMARY_TAG_FOUND, + ALT_TAG_FOUND +}; + +/// @brief Get the first value set for a tag +/// @param line Line to get the value from +/// @param tag Tag to get the value of +/// @param n Number of parameters passed +/// @return Which tag (if any) was found +template +static TagFoundType get_value(const AssDialogue *line, wxString tag, size_t n, ...) { + wxString alt; + if (tag == L"\\pos") alt = L"\\move"; + else if (tag == L"\\an") alt = L"\\a"; + else if (tag == L"\\clip") alt = L"\\iclip"; + + for (size_t i = 0; i < line->Blocks.size(); i++) { + const AssDialogueBlockOverride *ovr = dynamic_cast(line->Blocks[i]); + if (!ovr) continue; + + for (size_t j=0; j < ovr->Tags.size(); j++) { + const AssOverrideTag *cur = ovr->Tags[j]; + if ((cur->Name == tag || cur->Name == alt) && cur->Params.size() >= n) { + va_list argp; + va_start(argp, n); + for (size_t j = 0; j < n; j++) { + T *val = va_arg(argp, T *); + *val = cur->Params[j]->Get(*val); + } + va_end(argp); + return cur->Name == alt ? ALT_TAG_FOUND : PRIMARY_TAG_FOUND; + } + } + } + return TAG_NOT_FOUND; +} + template void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y) { int orgx,orgy; GetLinePosition(diag,x,y,orgx,orgy); } -/// @brief DOCME -/// @param diag -/// @param x -/// @param y -/// @param orgx -/// @param orgy template void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, int &orgy) { - if (!diag) { - x = INT_MIN; - y = INT_MIN; - orgx = INT_MIN; - orgy = INT_MIN; - return; - } - int margin[4]; for (int i=0;i<4;i++) margin[i] = diag->Margin[i]; int align = 2; @@ -452,9 +473,8 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, VideoContext::Get()->GetScriptSize(sw,sh); // Process margins - margin[3] = margin[2]; margin[1] = sw - margin[1]; - margin[3] = sh - margin[3]; + margin[3] = sh - margin[2]; // Position bool posSet = false; @@ -462,59 +482,23 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, // Overrides processing diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - for (size_t i=0;i(diag->Blocks.at(i)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - - // Position - if ((tag->Name == L"\\pos" || tag->Name == L"\\move") && tag->Params.size() >= 2) { - if (!posSet) { - x = tag->Params[0]->Get(); - y = tag->Params[1]->Get(); - posSet = true; - } - } - - // Alignment - else if ((tag->Name == L"\\an" || tag->Name == L"\\a") && tag->Params.size() >= 1) { - align = tag->Params[0]->Get(); - if (tag->Name == L"\\a") { - switch(align) { - case 1: case 2: case 3: - break; - case 5: case 6: case 7: - align += 2; - break; - case 9: case 10: case 11: - align -= 5; - break; - default: - align = 2; - break; - } - } - } - - // Origin - else if (!orgSet && tag->Name == L"\\org" && tag->Params.size() >= 2) { - orgx = tag->Params[0]->Get(); - orgy = tag->Params[1]->Get(); - parent->FromScriptCoords(&orgx, &orgy); - orgSet = true; - } + if (!get_value(diag, "\\pos", 2, &x, &y)) { + if (get_value(diag, "\\an", 1, &align) == ALT_TAG_FOUND) { + switch(align) { + case 1: case 2: case 3: + break; + case 5: case 6: case 7: + align += 2; + break; + case 9: case 10: case 11: + align -= 5; + break; + default: + align = 2; + break; } } - } - diag->ClearBlocks(); - - if (!posSet) { // Alignment type int hor = (align - 1) % 3; int vert = (align - 1) / 3; @@ -530,154 +514,71 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, parent->FromScriptCoords(&x, &y); - // No origin? - if (!orgSet) { + if (!get_value(diag, "\\org", 2, &orgx, &orgy)) { orgx = x; orgy = y; } -} - -/// @brief Get the destination of move, if any -/// @param diag -/// @param hasMove -/// @param x1 -/// @param y1 -/// @param x2 -/// @param y2 -/// @param t1 -/// @param t2 -template -void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) { - // Parse tags - hasMove = false; - diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - - // For each block - for (size_t i=0;i(diag->Blocks.at(i)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - - // Position - if (tag->Name == L"\\move" && tag->Params.size() >= 4) { - hasMove = true; - x1 = tag->Params[0]->Get(); - y1 = tag->Params[1]->Get(); - x2 = tag->Params[2]->Get(); - y2 = tag->Params[3]->Get(); - parent->FromScriptCoords(&x1, &y1); - parent->FromScriptCoords(&x2, &y2); - if (tag->Params.size() >= 6 && - !tag->Params[4]->ommited && - !tag->Params[5]->ommited) { - - t1 = tag->Params[4]->Get(); - t2 = tag->Params[5]->Get(); - } - return; - } - } - } + else { + parent->FromScriptCoords(&orgx, &orgy); } + + diag->ClearBlocks(); +} + +template +void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) { + diag->ParseASSTags(); + + hasMove = + get_value(diag, "\\move", 6, &x1, &y1, &x2, &y2, &t1, &t2) || + get_value(diag, "\\move", 4, &x1, &y1, &x2, &y2); + + if (hasMove) { + parent->FromScriptCoords(&x1, &y1); + parent->FromScriptCoords(&x2, &y2); + } + diag->ClearBlocks(); } -/// @brief Get line's rotation -/// @param diag -/// @param rx -/// @param ry -/// @param rz template void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) { - // Default values - rx = ry = rz = 0.0f; - - // No dialogue - if (!diag) return; + rx = ry = rz = 0.f; AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); if (style) { rz = style->angle; } - // Prepare overrides diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - if (blockn == 0) { - diag->ClearBlocks(); - return; - } - // Process override - override = dynamic_cast(diag->Blocks.at(0)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - if (tag->Name == L"\\frx" && tag->Params.size() == 1) { - rx = tag->Params[0]->Get(); - } - if (tag->Name == L"\\fry" && tag->Params.size() == 1) { - ry = tag->Params[0]->Get(); - } - if ((tag->Name == L"\\frz" || tag->Name == L"\fr") && tag->Params.size() == 1) { - rz = tag->Params[0]->Get(); - } - } - } + get_value(diag, L"\\frx", 1, &rx); + get_value(diag, L"\\fry", 1, &ry); + get_value(diag, L"\\frz", 1, &rz); + diag->ClearBlocks(); } -/// @brief Get line's scale -/// @param diag -/// @param scalX -/// @param scalY template void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) { - // Default values - scalX = scalY = 100.0f; + scalX = scalY = 100.f; + + AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); + if (style) { + scalX = style->scalex; + scalY = style->scaley; + } - // Prepare overrides diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - if (blockn == 0) { - diag->ClearBlocks(); - return; - } - // Process override - override = dynamic_cast(diag->Blocks.at(0)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - if (tag->Name == L"\\fscx" && tag->Params.size() == 1) { - scalX = tag->Params[0]->Get(); - } - if (tag->Name == L"\\fscy" && tag->Params.size() == 1) { - scalY = tag->Params[0]->Get(); - } - } - } + get_value(diag, L"\\fscx", 1, &scalX); + get_value(diag, L"\\fscy", 1, &scalY); + diag->ClearBlocks(); } -/// @brief Get line's clip -/// @param diag -/// @param x1 -/// @param y1 -/// @param x2 -/// @param y2 -/// @param inverse template void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse) { - // Default values x1 = y1 = 0; int sw,sh; VideoContext::Get()->GetScriptSize(sw,sh); @@ -685,85 +586,35 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int y2 = sh-1; inverse = false; - // Prepare overrides diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - if (blockn == 0) { - diag->ClearBlocks(); - return; - } - - // Process override - override = dynamic_cast(diag->Blocks.at(0)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - if (tag->Name == L"\\clip" && tag->Params.size() == 4) { - x1 = tag->Params[0]->Get(); - y1 = tag->Params[1]->Get(); - x2 = tag->Params[2]->Get(); - y2 = tag->Params[3]->Get(); - inverse = false; - } - else if (tag->Name == L"\\iclip" && tag->Params.size() == 4) { - x1 = tag->Params[0]->Get(); - y1 = tag->Params[1]->Get(); - x2 = tag->Params[2]->Get(); - y2 = tag->Params[3]->Get(); - inverse = true; - } - } - } + inverse = get_value(diag, L"\\clip", 4, &x1, &y1, &x2, &y2) == ALT_TAG_FOUND; diag->ClearBlocks(); parent->FromScriptCoords(&x1, &y1); parent->FromScriptCoords(&x2, &y2); } -/// @brief Get line vector clip, if it exists -/// @param diag -/// @param scale -/// @param inverse template wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) { - // Prepare overrides - wxString result; scale = 1; inverse = false; diag->ParseASSTags(); - AssDialogueBlockOverride *override; - AssOverrideTag *tag; - size_t blockn = diag->Blocks.size(); - if (blockn == 0) { - diag->ClearBlocks(); - return result; - } - // Process override - override = dynamic_cast(diag->Blocks.at(0)); - if (override) { - for (size_t j=0;jTags.size();j++) { - tag = override->Tags.at(j); - if (tag->Name == L"\\clip" || tag->Name == L"\\iclip") { - if (tag->Params.size() == 1) { - result = tag->Params[0]->Get(); - } - else if (tag->Params.size() == 2) { - scale = tag->Params[0]->Get(); - result = tag->Params[1]->Get(); - } - else if (tag->Params.size() == 4) { - int x1 = tag->Params[0]->Get(), - y1 = tag->Params[1]->Get(), - x2 = tag->Params[2]->Get(), - y2 = tag->Params[3]->Get(); - result = wxString::Format(L"m %d %d l %d %d %d %d %d %d", x1, y1, x2, y1, x2, y2, x1, y2); - } - inverse = tag->Name == L"\\iclip"; - } - } + int x1, y1, x2, y2; + TagFoundType res = get_value(diag, L"\\clip", 4, &x1, &y1, &x2, &y2); + if (res) { + inverse = res == ALT_TAG_FOUND; + diag->ClearBlocks(); + return wxString::Format(L"m %d %d l %d %d %d %d %d %d", x1, y1, x2, y1, x2, y2, x1, y2); + } + wxString result; + wxString scaleStr; + res = get_value(diag, L"\\clip", 2, &scaleStr, &result); + inverse = res == ALT_TAG_FOUND; + if (!scaleStr.empty()) { + long s; + scaleStr.ToLong(&s); + scale = s; } diag->ClearBlocks(); return result; diff --git a/aegisub/src/visual_tool_rotatexy.cpp b/aegisub/src/visual_tool_rotatexy.cpp index a6d84d5dc..1f0077301 100644 --- a/aegisub/src/visual_tool_rotatexy.cpp +++ b/aegisub/src/visual_tool_rotatexy.cpp @@ -58,7 +58,6 @@ VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& v /// @brief Draw void VisualToolRotateXY::Draw() { - // Get line to draw AssDialogue *line = GetActiveDialogueLine(); if (!line) return; @@ -168,14 +167,13 @@ void VisualToolRotateXY::Draw() { /// @brief Start holding bool VisualToolRotateXY::InitializeHold() { + if (!curDiag) return false; GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLineRotation(curDiag,origAngleX,origAngleY,rz); startAngleX = (orgy-video.y)*2.f; startAngleY = (video.x-orgx)*2.f; curAngleX = origAngleX; curAngleY = origAngleY; - curDiag->StripTag(L"\\frx"); - curDiag->StripTag(L"\\fry"); return true; } @@ -220,8 +218,8 @@ void VisualToolRotateXY::CommitHold() { /// @brief Get \\org pivot void VisualToolRotateXY::PopulateFeatureList() { - // Get line curDiag = GetActiveDialogueLine(); + if (!curDiag) return; GetLinePosition(curDiag,odx,ody,orgx,orgy); // Set features @@ -252,6 +250,7 @@ void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) { /// @brief Refresh void VisualToolRotateXY::DoRefresh() { AssDialogue *line = GetActiveDialogueLine(); + if (!line) return; GetLinePosition(line,odx,ody,orgx,orgy); GetLineRotation(line,curAngleX,curAngleY,rz); } diff --git a/aegisub/src/visual_tool_rotatez.cpp b/aegisub/src/visual_tool_rotatez.cpp index cfe81eb30..18e458ccf 100644 --- a/aegisub/src/visual_tool_rotatez.cpp +++ b/aegisub/src/visual_tool_rotatez.cpp @@ -189,8 +189,8 @@ void VisualToolRotateZ::CommitHold() { /// @brief Get \\org pivot void VisualToolRotateZ::PopulateFeatureList() { - // Get line curDiag = GetActiveDialogueLine(); + if (!curDiag) return; GetLinePosition(curDiag,odx,ody,orgx,orgy); // Set features @@ -221,7 +221,7 @@ void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) { /// @brief Refresh void VisualToolRotateZ::DoRefresh() { AssDialogue *line = GetActiveDialogueLine(); + if (!line) return; GetLinePosition(line,odx,ody,orgx,orgy); GetLineRotation(line,rx,ry,curAngle); } -