From 30a0b7e82b99894b723b1e7bafcd47757d3af5da Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Wed, 10 Sep 2008 16:13:54 +0000 Subject: [PATCH] Add support for new override tags: \iclip \fax \fay \xshad \yshad \xbord \ybord \blur Support redefined override tags: \move (float-pos) \pos (float-pos) \be (variable) Make visual typesetting understand inverse clips and edit them correctly. Make vector clip visual tool able to convert a rectangular clip to a vector clip. What's missing: Proper rendering of inverse vector clips in visual tool overlay. Originally committed to SVN as r2336. --- aegisub/ass_override.cpp | 87 ++++++++++++++++++++++++----- aegisub/ass_override.h | 4 +- aegisub/visual_tool.cpp | 26 +++++++-- aegisub/visual_tool.h | 4 +- aegisub/visual_tool_clip.cpp | 25 ++++++--- aegisub/visual_tool_clip.h | 1 + aegisub/visual_tool_vector_clip.cpp | 25 +++++++-- aegisub/visual_tool_vector_clip.h | 1 + lua51/lua51_vc9.vcproj | 24 ++++---- 9 files changed, 152 insertions(+), 45 deletions(-) diff --git a/aegisub/ass_override.cpp b/aegisub/ass_override.cpp index 66b761c34..c7dcb7fda 100644 --- a/aegisub/ass_override.cpp +++ b/aegisub/ass_override.cpp @@ -232,11 +232,31 @@ void AssOverrideTagProto::LoadProtos () { proto.back().name = _T("\\bord"); proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + // \xbord + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\xbord"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + + // \ybord + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\ybord"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + // \shad proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\shad"); proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + // \xshad + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\xshad"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + + // \yshad + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\yshad"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_SIZE)); + // \fade(,,,,,,) proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\fade"); @@ -251,10 +271,10 @@ void AssOverrideTagProto::LoadProtos () { // \move(,,,[,,]) proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\move"); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START)); proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_6,PARCLASS_RELATIVE_TIME_START)); @@ -272,6 +292,20 @@ void AssOverrideTagProto::LoadProtos () { proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL)); proto.back().params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING)); + // \iclip(,,,) + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\iclip"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + + // \iclip([,]) + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\iclip"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,OPTIONAL_2,PARCLASS_NORMAL)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_TEXT,NOT_OPTIONAL,PARCLASS_DRAWING)); + // \fscx proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\fscx"); @@ -285,8 +319,8 @@ void AssOverrideTagProto::LoadProtos () { // \pos(,) proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\pos"); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_X)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_ABSOLUTE_POS_Y)); // \org(,) proto.push_back(AssOverrideTagProto()); @@ -330,6 +364,16 @@ void AssOverrideTagProto::LoadProtos () { proto.back().name = _T("\\fr"); proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); + // \fax + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\fax"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); + + // \fay + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\fay"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); + // \1c&H& proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\1c"); @@ -385,10 +429,15 @@ void AssOverrideTagProto::LoadProtos () { proto.back().name = _T("\\kf"); proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_KARAOKE)); - // \be<0/1> + // \be proto.push_back(AssOverrideTagProto()); proto.back().name = _T("\\be"); - proto.back().params.push_back(AssOverrideParamProto(VARDATA_BOOL,NOT_OPTIONAL,PARCLASS_NORMAL)); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_INT,NOT_OPTIONAL,PARCLASS_NORMAL)); + + // \blur + proto.push_back(AssOverrideTagProto()); + proto.back().name = _T("\\blur"); + proto.back().params.push_back(AssOverrideParamProto(VARDATA_FLOAT,NOT_OPTIONAL,PARCLASS_NORMAL)); // \fn proto.push_back(AssOverrideTagProto()); @@ -502,7 +551,7 @@ void AssOverrideTag::Clear() { //////////////////////////// // Parses text and sets tag -void AssOverrideTag::SetText (wxString text) { +void AssOverrideTag::SetText (const wxString &text) { // Determine name Name = _T(""); AssOverrideTagProto *proto; @@ -537,7 +586,7 @@ bool AssOverrideTag::IsValid() { ///////////////////// // Parses parameters -void AssOverrideTag::ParseParameters(wxString text) { +void AssOverrideTag::ParseParameters(const wxString &text) { // Clear first Clear(); @@ -551,7 +600,8 @@ void AssOverrideTag::ParseParameters(wxString text) { if (text.IsEmpty() || text[0] != _T('(')) { // There's just one (or none at all) parameter (because there's no parantheses) // This means text is all our parameters - paramList.Add(text.Trim(true).Trim(false)); + wxString param(text); + paramList.Add(param.Trim(true).Trim(false)); // Only using goto here to avoid yet another nested block (keeps the code cleaner!) goto end_tokenizing; } @@ -613,7 +663,7 @@ end_tokenizing: } // Find prototype - bool clipOnce = true; + bool clipOnce = true, iclipOnce = true; AssOverrideTagProto *proto = NULL; for (std::list::iterator cur=AssOverrideTagProto::proto.begin();cur!=AssOverrideTagProto::proto.end();cur++) { if (Name == (*cur).name) { @@ -621,6 +671,10 @@ end_tokenizing: clipOnce = false; continue; } + if (Name == _T("\\iclip") && totalPars != 4 && iclipOnce) { + iclipOnce = false; + continue; + } proto = &(*cur); break; } @@ -731,7 +785,14 @@ wxString AssOverrideTag::ToString() { // Determine if it needs parentheses bool parenthesis = false; - if (Name == _T("\\t") || Name == _T("\\pos") || Name == _T("\\fad") || Name == _T("\\org") || Name == _T("\\clip") || Name == _T("\\move") || Name == _T("\\fade")) parenthesis = true; + if (Name == _T("\\t") || + Name == _T("\\pos") || + Name == _T("\\fad") || + Name == _T("\\org") || + Name == _T("\\clip") || + Name == _T("\\iclip") || + Name == _T("\\move") || + Name == _T("\\fade")) parenthesis = true; if (parenthesis) result += _T("("); // Add parameters diff --git a/aegisub/ass_override.h b/aegisub/ass_override.h index 5e6a1ada8..0daaf9db4 100644 --- a/aegisub/ass_override.h +++ b/aegisub/ass_override.h @@ -98,9 +98,9 @@ public: ~AssOverrideTag(); bool IsValid(); - void ParseParameters(wxString text); + void ParseParameters(const wxString &text); void Clear(); - void SetText(wxString text); + void SetText(const wxString &text); wxString ToString(); }; diff --git a/aegisub/visual_tool.cpp b/aegisub/visual_tool.cpp index 8399beebc..30196e8d2 100644 --- a/aegisub/visual_tool.cpp +++ b/aegisub/visual_tool.cpp @@ -584,13 +584,14 @@ void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) { /////////////////// // Get line's clip -void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2) { +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); x2 = sw-1; y2 = sh-1; + inverse = false; // Prepare overrides diag->ParseASSTags(); @@ -612,6 +613,14 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2) y1 = tag->Params[1]->AsInt(); x2 = tag->Params[2]->AsInt(); y2 = tag->Params[3]->AsInt(); + inverse = false; + } + else if (tag->Name == _T("\\iclip") && tag->Params.size() == 4) { + x1 = tag->Params[0]->AsInt(); + y1 = tag->Params[1]->AsInt(); + x2 = tag->Params[2]->AsInt(); + y2 = tag->Params[3]->AsInt(); + inverse = true; } } } @@ -621,10 +630,11 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2) ////////////////////////////////////// // Get line vector clip, if it exists -wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale) { +wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) { // Prepare overrides wxString result; scale = 1; + inverse = false; diag->ParseASSTags(); AssDialogueBlockOverride *override; AssOverrideTag *tag; @@ -639,14 +649,22 @@ wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale) { if (override) { for (size_t j=0;jTags.size();j++) { tag = override->Tags.at(j); - if (tag->Name == _T("\\clip")) { + if (tag->Name == _T("\\clip") || tag->Name == _T("\\iclip")) { if (tag->Params.size() == 1) { result = tag->Params[0]->AsText(); } - if (tag->Params.size() == 2) { + else if (tag->Params.size() == 2) { scale = tag->Params[0]->AsInt(); result = tag->Params[1]->AsText(); } + else if (tag->Params.size() == 4) { + int x1 = tag->Params[0]->AsInt(), + y1 = tag->Params[1]->AsInt(), + x2 = tag->Params[2]->AsInt(), + y2 = tag->Params[3]->AsInt(); + result = wxString::Format(_T("m %d %d l %d %d %d %d %d %d"), x1, y1, x2, y1, x2, y2, x1, y2); + } + inverse = tag->Name == _T("\\iclip"); } } } diff --git a/aegisub/visual_tool.h b/aegisub/visual_tool.h index eeeb1d588..8c51bedd5 100644 --- a/aegisub/visual_tool.h +++ b/aegisub/visual_tool.h @@ -107,8 +107,8 @@ protected: void GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2); void GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz); void GetLineScale(AssDialogue *diag,float &scalX,float &scalY); - void GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2); - wxString GetLineVectorClip(AssDialogue *diag,int &scale); + void GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse); + wxString GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse); void FillPositionData(); void SetOverride(wxString tag,wxString value); diff --git a/aegisub/visual_tool_clip.cpp b/aegisub/visual_tool_clip.cpp index de3f4bb1a..8ee4d6c08 100644 --- a/aegisub/visual_tool_clip.cpp +++ b/aegisub/visual_tool_clip.cpp @@ -55,8 +55,9 @@ VisualToolClip::VisualToolClip(VideoDisplay *_parent) curX1 = curY1 = 0; curX2 = sw; curY2 = sh; + inverse = false; AssDialogue *line = GetActiveDialogueLine(); - if (line) GetLineClip(line,curX1,curY1,curX2,curY2); + if (line) GetLineClip(line,curX1,curY1,curX2,curY2,inverse); } @@ -76,7 +77,7 @@ void VisualToolClip::Draw() { if (!line) return; // Get position - if (!dragging && !holding) GetLineClip(line,curX1,curY1,curX2,curY2); + if (!dragging && !holding) GetLineClip(line,curX1,curY1,curX2,curY2,inverse); int dx1 = curX1; int dy1 = curY1; int dx2 = curX2; @@ -90,10 +91,15 @@ void VisualToolClip::Draw() { // Draw outside area SetLineColour(colour[3],0.0f); SetFillColour(wxColour(0,0,0),0.5f); - DrawRectangle(0,0,sw,dy1); - DrawRectangle(0,dy2,sw,sh); - DrawRectangle(0,dy1,dx1,dy2); - DrawRectangle(dx2,dy1,sw,dy2); + if (inverse) { + DrawRectangle(dx1,dy1,dx2,dy2); + } + else { + DrawRectangle(0,0,sw,dy1); + DrawRectangle(0,dy2,sw,sh); + DrawRectangle(0,dy1,dx1,dy2); + DrawRectangle(dx2,dy1,sw,dy2); + } // Draw circles SetLineColour(colour[0]); @@ -114,6 +120,7 @@ void VisualToolClip::InitializeHold() { startX = mouseX; startY = mouseY; curDiag->StripTag(_T("\\clip")); + curDiag->StripTag(_T("\\iclip")); } @@ -144,7 +151,10 @@ void VisualToolClip::UpdateHold() { /////////////// // Commit hold void VisualToolClip::CommitHold() { - SetOverride(_T("\\clip"),wxString::Format(_T("(%i,%i,%i,%i)"),curX1,curY1,curX2,curY2)); + if (inverse) + SetOverride(_T("\\iclip"),wxString::Format(_T("(%i,%i,%i,%i)"),curX1,curY1,curX2,curY2)); + else + SetOverride(_T("\\clip"),wxString::Format(_T("(%i,%i,%i,%i)"),curX1,curY1,curX2,curY2)); } @@ -201,6 +211,7 @@ void VisualToolClip::PopulateFeatureList() { void VisualToolClip::InitializeDrag(VisualDraggableFeature &feature) { curDiag = GetActiveDialogueLine(); curDiag->StripTag(_T("\\clip")); + curDiag->StripTag(_T("\\iclip")); } diff --git a/aegisub/visual_tool_clip.h b/aegisub/visual_tool_clip.h index 7e418a41b..9af9d9530 100644 --- a/aegisub/visual_tool_clip.h +++ b/aegisub/visual_tool_clip.h @@ -47,6 +47,7 @@ class VisualToolClip : public VisualTool { private: int startX,startY,curX1,curY1,curX2,curY2; + bool inverse; bool CanHold() { return true; } void InitializeHold(); diff --git a/aegisub/visual_tool_vector_clip.cpp b/aegisub/visual_tool_vector_clip.cpp index 8cfcbd528..5e542c088 100644 --- a/aegisub/visual_tool_vector_clip.cpp +++ b/aegisub/visual_tool_vector_clip.cpp @@ -123,6 +123,7 @@ void VisualToolVectorClip::Draw() { spline.GetPointList(points,pointCurve); // Draw stencil mask + // FIXME: This should understand inverse clips too glEnable(GL_STENCIL_TEST); glColorMask(0,0,0,0); glStencilFunc(GL_NEVER,1,1); @@ -273,7 +274,10 @@ void VisualToolVectorClip::UpdateDrag(VisualDraggableFeature &feature) { ////////// // Commit void VisualToolVectorClip::CommitDrag(VisualDraggableFeature &feature) { - SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); + if (inverse) + SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); + else + SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); } @@ -294,7 +298,10 @@ void VisualToolVectorClip::ClickedFeature(VisualDraggableFeature &feature) { // Erase and save changes spline.curves.erase(cur); - SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); + if (inverse) + SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); + else + SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); curFeature = -1; Commit(true); return; @@ -389,7 +396,10 @@ void VisualToolVectorClip::InitializeHold() { } // Commit - SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); + if (inverse) + SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); + else + SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); Commit(true); } @@ -460,7 +470,12 @@ void VisualToolVectorClip::CommitHold() { if (!holding && mode == 7) spline.Smooth(); // Save it - if (mode != 3 && mode != 4) SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); + if (mode != 3 && mode != 4) { + if (inverse) + SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); + else + SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); + } // End freedraw if (!holding && (mode == 6 || mode == 7)) SetMode(0); @@ -478,7 +493,7 @@ void VisualToolVectorClip::DoRefresh() { // Get clip vector wxString vect; int scale; - vect = GetLineVectorClip(line,scale); + vect = GetLineVectorClip(line,scale,inverse); //if (!vect.IsEmpty()) return; spline.DecodeFromASS(vect); PopulateFeatureList(); diff --git a/aegisub/visual_tool_vector_clip.h b/aegisub/visual_tool_vector_clip.h index 4ab82ddc2..381e98ab2 100644 --- a/aegisub/visual_tool_vector_clip.h +++ b/aegisub/visual_tool_vector_clip.h @@ -52,6 +52,7 @@ private: wxToolBar *toolBar; int mode; int lastX,lastY; + bool inverse; void SetMode(int mode); diff --git a/lua51/lua51_vc9.vcproj b/lua51/lua51_vc9.vcproj index 9bf725822..a50e98d0f 100644 --- a/lua51/lua51_vc9.vcproj +++ b/lua51/lua51_vc9.vcproj @@ -21,8 +21,8 @@