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.
This commit is contained in:
Thomas Goyne 2010-06-24 01:23:43 +00:00
parent 4bb8e8ea22
commit 50d1b3ed2d
4 changed files with 117 additions and 281 deletions

View file

@ -58,6 +58,7 @@
#include "subtitle_format.h" #include "subtitle_format.h"
#include "text_file_reader.h" #include "text_file_reader.h"
#include "text_file_writer.h" #include "text_file_writer.h"
#include "utils.h"
#include "version.h" #include "version.h"
#include "vfr.h" #include "vfr.h"
@ -412,13 +413,10 @@ void AssFile::AddLine(wxString data,wxString group,int &version,wxString *outGro
} }
void AssFile::Clear() { void AssFile::Clear() {
for (entryIter cur=Line.begin();cur != Line.end();cur++) { delete_clear(Line);
delete *cur;
}
Line.clear();
loaded = false; loaded = false;
filename = _T(""); filename.clear();
Modified = false; Modified = false;
} }
@ -756,12 +754,7 @@ bool AssFile::IsModified() {
void AssFile::FlagAsModified(wxString desc) { void AssFile::FlagAsModified(wxString desc) {
if (!RedoStack.empty()) { if (!RedoStack.empty()) {
//StackPush(); delete_clear(RedoStack);
//UndoStack.push_back(new AssFile(*UndoStack.back()));
for (std::list<AssFile*>::iterator cur=RedoStack.begin();cur!=RedoStack.end();cur++) {
delete *cur;
}
RedoStack.clear();
} }
Modified = true; Modified = true;
@ -841,15 +834,8 @@ void AssFile::StackRedo() {
} }
void AssFile::StackClear() { void AssFile::StackClear() {
for (std::list<AssFile*>::iterator cur=UndoStack.begin();cur!=UndoStack.end();cur++) { delete_clear(UndoStack);
delete *cur; delete_clear(RedoStack);
}
UndoStack.clear();
for (std::list<AssFile*>::iterator cur=RedoStack.begin();cur!=RedoStack.end();cur++) {
delete *cur;
}
RedoStack.clear();
Popping = false; Popping = false;
} }

View file

@ -410,32 +410,53 @@ void VisualTool<FeatureType>::SetEditbox(int lineN) {
} }
} }
/// @brief Get position of line enum TagFoundType {
/// @param diag TAG_NOT_FOUND = 0,
/// @param x PRIMARY_TAG_FOUND,
/// @param y 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<class T>
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<const AssDialogueBlockOverride*>(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<T>(*val);
}
va_end(argp);
return cur->Name == alt ? ALT_TAG_FOUND : PRIMARY_TAG_FOUND;
}
}
}
return TAG_NOT_FOUND;
}
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y) { void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y) {
int orgx,orgy; int orgx,orgy;
GetLinePosition(diag,x,y,orgx,orgy); GetLinePosition(diag,x,y,orgx,orgy);
} }
/// @brief DOCME
/// @param diag
/// @param x
/// @param y
/// @param orgx
/// @param orgy
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, int &orgy) { void VisualTool<FeatureType>::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]; int margin[4];
for (int i=0;i<4;i++) margin[i] = diag->Margin[i]; for (int i=0;i<4;i++) margin[i] = diag->Margin[i];
int align = 2; int align = 2;
@ -452,9 +473,8 @@ void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y,
VideoContext::Get()->GetScriptSize(sw,sh); VideoContext::Get()->GetScriptSize(sw,sh);
// Process margins // Process margins
margin[3] = margin[2];
margin[1] = sw - margin[1]; margin[1] = sw - margin[1];
margin[3] = sh - margin[3]; margin[3] = sh - margin[2];
// Position // Position
bool posSet = false; bool posSet = false;
@ -462,30 +482,9 @@ void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y,
// Overrides processing // Overrides processing
diag->ParseASSTags(); diag->ParseASSTags();
AssDialogueBlockOverride *override;
AssOverrideTag *tag;
size_t blockn = diag->Blocks.size();
for (size_t i=0;i<blockn;i++) {
if (posSet && orgSet) break;
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(i)); if (!get_value<int>(diag, "\\pos", 2, &x, &y)) {
if (override) { if (get_value<int>(diag, "\\an", 1, &align) == ALT_TAG_FOUND) {
for (size_t j=0;j<override->Tags.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<int>();
y = tag->Params[1]->Get<int>();
posSet = true;
}
}
// Alignment
else if ((tag->Name == L"\\an" || tag->Name == L"\\a") && tag->Params.size() >= 1) {
align = tag->Params[0]->Get<int>();
if (tag->Name == L"\\a") {
switch(align) { switch(align) {
case 1: case 2: case 3: case 1: case 2: case 3:
break; break;
@ -500,21 +499,6 @@ void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y,
break; break;
} }
} }
}
// Origin
else if (!orgSet && tag->Name == L"\\org" && tag->Params.size() >= 2) {
orgx = tag->Params[0]->Get<int>();
orgy = tag->Params[1]->Get<int>();
parent->FromScriptCoords(&orgx, &orgy);
orgSet = true;
}
}
}
}
diag->ClearBlocks();
if (!posSet) {
// Alignment type // Alignment type
int hor = (align - 1) % 3; int hor = (align - 1) % 3;
int vert = (align - 1) / 3; int vert = (align - 1) / 3;
@ -530,154 +514,71 @@ void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y,
parent->FromScriptCoords(&x, &y); parent->FromScriptCoords(&x, &y);
// No origin? if (!get_value<int>(diag, "\\org", 2, &orgx, &orgy)) {
if (!orgSet) {
orgx = x; orgx = x;
orgy = y; orgy = y;
} }
else {
parent->FromScriptCoords(&orgx, &orgy);
}
diag->ClearBlocks();
}
template<class FeatureType>
void VisualTool<FeatureType>::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) {
diag->ParseASSTags();
hasMove =
get_value<int>(diag, "\\move", 6, &x1, &y1, &x2, &y2, &t1, &t2) ||
get_value<int>(diag, "\\move", 4, &x1, &y1, &x2, &y2);
if (hasMove) {
parent->FromScriptCoords(&x1, &y1);
parent->FromScriptCoords(&x2, &y2);
} }
/// @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<class FeatureType>
void VisualTool<FeatureType>::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<blockn;i++) {
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(i));
if (override) {
for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j);
// Position
if (tag->Name == L"\\move" && tag->Params.size() >= 4) {
hasMove = true;
x1 = tag->Params[0]->Get<int>();
y1 = tag->Params[1]->Get<int>();
x2 = tag->Params[2]->Get<int>();
y2 = tag->Params[3]->Get<int>();
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<int>();
t2 = tag->Params[5]->Get<int>();
}
return;
}
}
}
}
diag->ClearBlocks(); diag->ClearBlocks();
} }
/// @brief Get line's rotation
/// @param diag
/// @param rx
/// @param ry
/// @param rz
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) { void VisualTool<FeatureType>::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) {
// Default values rx = ry = rz = 0.f;
rx = ry = rz = 0.0f;
// No dialogue
if (!diag) return;
AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style);
if (style) { if (style) {
rz = style->angle; rz = style->angle;
} }
// Prepare overrides
diag->ParseASSTags(); diag->ParseASSTags();
AssDialogueBlockOverride *override;
AssOverrideTag *tag;
size_t blockn = diag->Blocks.size();
if (blockn == 0) {
diag->ClearBlocks();
return;
}
// Process override get_value<double>(diag, L"\\frx", 1, &rx);
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(0)); get_value<double>(diag, L"\\fry", 1, &ry);
if (override) { get_value<double>(diag, L"\\frz", 1, &rz);
for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j);
if (tag->Name == L"\\frx" && tag->Params.size() == 1) {
rx = tag->Params[0]->Get<double>();
}
if (tag->Name == L"\\fry" && tag->Params.size() == 1) {
ry = tag->Params[0]->Get<double>();
}
if ((tag->Name == L"\\frz" || tag->Name == L"\fr") && tag->Params.size() == 1) {
rz = tag->Params[0]->Get<double>();
}
}
}
diag->ClearBlocks(); diag->ClearBlocks();
} }
/// @brief Get line's scale
/// @param diag
/// @param scalX
/// @param scalY
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) { void VisualTool<FeatureType>::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) {
// Default values scalX = scalY = 100.f;
scalX = scalY = 100.0f;
AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style);
if (style) {
scalX = style->scalex;
scalY = style->scaley;
}
// Prepare overrides
diag->ParseASSTags(); diag->ParseASSTags();
AssDialogueBlockOverride *override;
AssOverrideTag *tag;
size_t blockn = diag->Blocks.size();
if (blockn == 0) {
diag->ClearBlocks();
return;
}
// Process override get_value<double>(diag, L"\\fscx", 1, &scalX);
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(0)); get_value<double>(diag, L"\\fscy", 1, &scalY);
if (override) {
for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j);
if (tag->Name == L"\\fscx" && tag->Params.size() == 1) {
scalX = tag->Params[0]->Get<double>();
}
if (tag->Name == L"\\fscy" && tag->Params.size() == 1) {
scalY = tag->Params[0]->Get<double>();
}
}
}
diag->ClearBlocks(); diag->ClearBlocks();
} }
/// @brief Get line's clip
/// @param diag
/// @param x1
/// @param y1
/// @param x2
/// @param y2
/// @param inverse
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse) { void VisualTool<FeatureType>::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse) {
// Default values
x1 = y1 = 0; x1 = y1 = 0;
int sw,sh; int sw,sh;
VideoContext::Get()->GetScriptSize(sw,sh); VideoContext::Get()->GetScriptSize(sw,sh);
@ -685,85 +586,35 @@ void VisualTool<FeatureType>::GetLineClip(AssDialogue *diag,int &x1,int &y1,int
y2 = sh-1; y2 = sh-1;
inverse = false; inverse = false;
// Prepare overrides
diag->ParseASSTags(); diag->ParseASSTags();
AssDialogueBlockOverride *override; inverse = get_value<int>(diag, L"\\clip", 4, &x1, &y1, &x2, &y2) == ALT_TAG_FOUND;
AssOverrideTag *tag;
size_t blockn = diag->Blocks.size();
if (blockn == 0) {
diag->ClearBlocks();
return;
}
// Process override
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(0));
if (override) {
for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j);
if (tag->Name == L"\\clip" && tag->Params.size() == 4) {
x1 = tag->Params[0]->Get<int>();
y1 = tag->Params[1]->Get<int>();
x2 = tag->Params[2]->Get<int>();
y2 = tag->Params[3]->Get<int>();
inverse = false;
}
else if (tag->Name == L"\\iclip" && tag->Params.size() == 4) {
x1 = tag->Params[0]->Get<int>();
y1 = tag->Params[1]->Get<int>();
x2 = tag->Params[2]->Get<int>();
y2 = tag->Params[3]->Get<int>();
inverse = true;
}
}
}
diag->ClearBlocks(); diag->ClearBlocks();
parent->FromScriptCoords(&x1, &y1); parent->FromScriptCoords(&x1, &y1);
parent->FromScriptCoords(&x2, &y2); parent->FromScriptCoords(&x2, &y2);
} }
/// @brief Get line vector clip, if it exists
/// @param diag
/// @param scale
/// @param inverse
template<class FeatureType> template<class FeatureType>
wxString VisualTool<FeatureType>::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) { wxString VisualTool<FeatureType>::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) {
// Prepare overrides
wxString result;
scale = 1; scale = 1;
inverse = false; inverse = false;
diag->ParseASSTags(); diag->ParseASSTags();
AssDialogueBlockOverride *override;
AssOverrideTag *tag;
size_t blockn = diag->Blocks.size();
if (blockn == 0) {
diag->ClearBlocks();
return result;
}
// Process override int x1, y1, x2, y2;
override = dynamic_cast<AssDialogueBlockOverride*>(diag->Blocks.at(0)); TagFoundType res = get_value<int>(diag, L"\\clip", 4, &x1, &y1, &x2, &y2);
if (override) { if (res) {
for (size_t j=0;j<override->Tags.size();j++) { inverse = res == ALT_TAG_FOUND;
tag = override->Tags.at(j); diag->ClearBlocks();
if (tag->Name == L"\\clip" || tag->Name == L"\\iclip") { return wxString::Format(L"m %d %d l %d %d %d %d %d %d", x1, y1, x2, y1, x2, y2, x1, y2);
if (tag->Params.size() == 1) {
result = tag->Params[0]->Get<wxString>();
}
else if (tag->Params.size() == 2) {
scale = tag->Params[0]->Get<int>();
result = tag->Params[1]->Get<wxString>();
}
else if (tag->Params.size() == 4) {
int x1 = tag->Params[0]->Get<int>(),
y1 = tag->Params[1]->Get<int>(),
x2 = tag->Params[2]->Get<int>(),
y2 = tag->Params[3]->Get<int>();
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";
}
} }
wxString result;
wxString scaleStr;
res = get_value<wxString>(diag, L"\\clip", 2, &scaleStr, &result);
inverse = res == ALT_TAG_FOUND;
if (!scaleStr.empty()) {
long s;
scaleStr.ToLong(&s);
scale = s;
} }
diag->ClearBlocks(); diag->ClearBlocks();
return result; return result;

View file

@ -58,7 +58,6 @@ VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& v
/// @brief Draw /// @brief Draw
void VisualToolRotateXY::Draw() { void VisualToolRotateXY::Draw() {
// Get line to draw
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
if (!line) return; if (!line) return;
@ -168,14 +167,13 @@ void VisualToolRotateXY::Draw() {
/// @brief Start holding /// @brief Start holding
bool VisualToolRotateXY::InitializeHold() { bool VisualToolRotateXY::InitializeHold() {
if (!curDiag) return false;
GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLinePosition(curDiag,odx,ody,orgx,orgy);
GetLineRotation(curDiag,origAngleX,origAngleY,rz); GetLineRotation(curDiag,origAngleX,origAngleY,rz);
startAngleX = (orgy-video.y)*2.f; startAngleX = (orgy-video.y)*2.f;
startAngleY = (video.x-orgx)*2.f; startAngleY = (video.x-orgx)*2.f;
curAngleX = origAngleX; curAngleX = origAngleX;
curAngleY = origAngleY; curAngleY = origAngleY;
curDiag->StripTag(L"\\frx");
curDiag->StripTag(L"\\fry");
return true; return true;
} }
@ -220,8 +218,8 @@ void VisualToolRotateXY::CommitHold() {
/// @brief Get \\org pivot /// @brief Get \\org pivot
void VisualToolRotateXY::PopulateFeatureList() { void VisualToolRotateXY::PopulateFeatureList() {
// Get line
curDiag = GetActiveDialogueLine(); curDiag = GetActiveDialogueLine();
if (!curDiag) return;
GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLinePosition(curDiag,odx,ody,orgx,orgy);
// Set features // Set features
@ -252,6 +250,7 @@ void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) {
/// @brief Refresh /// @brief Refresh
void VisualToolRotateXY::DoRefresh() { void VisualToolRotateXY::DoRefresh() {
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
GetLinePosition(line,odx,ody,orgx,orgy); GetLinePosition(line,odx,ody,orgx,orgy);
GetLineRotation(line,curAngleX,curAngleY,rz); GetLineRotation(line,curAngleX,curAngleY,rz);
} }

View file

@ -189,8 +189,8 @@ void VisualToolRotateZ::CommitHold() {
/// @brief Get \\org pivot /// @brief Get \\org pivot
void VisualToolRotateZ::PopulateFeatureList() { void VisualToolRotateZ::PopulateFeatureList() {
// Get line
curDiag = GetActiveDialogueLine(); curDiag = GetActiveDialogueLine();
if (!curDiag) return;
GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLinePosition(curDiag,odx,ody,orgx,orgy);
// Set features // Set features
@ -221,7 +221,7 @@ void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) {
/// @brief Refresh /// @brief Refresh
void VisualToolRotateZ::DoRefresh() { void VisualToolRotateZ::DoRefresh() {
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
GetLinePosition(line,odx,ody,orgx,orgy); GetLinePosition(line,odx,ody,orgx,orgy);
GetLineRotation(line,rx,ry,curAngle); GetLineRotation(line,rx,ry,curAngle);
} }