mirror of https://github.com/odrling/Aegisub
Barely function vector clip tool implemented
Originally committed to SVN as r1364.
This commit is contained in:
parent
5e25ffe30b
commit
570321722b
|
@ -222,6 +222,7 @@ aegisub_SOURCES = \
|
||||||
visual_tool_rotatexy.cpp \
|
visual_tool_rotatexy.cpp \
|
||||||
visual_tool_rotatez.cpp \
|
visual_tool_rotatez.cpp \
|
||||||
visual_tool_scale.cpp \
|
visual_tool_scale.cpp \
|
||||||
|
visual_tool_vector_clip.cpp \
|
||||||
MatroskaParser.c
|
MatroskaParser.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
|
|
|
@ -101,6 +101,19 @@ void OpenGLWrapper::DrawLine(float x1,float y1,float x2,float y2) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// Draw line
|
||||||
|
void OpenGLWrapper::DrawDashedLine(float x1,float y1,float x2,float y2,float step) {
|
||||||
|
float dist = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
|
||||||
|
int steps = (dist-20)/step;
|
||||||
|
double stepx = double(x2-x1)/steps;
|
||||||
|
double stepy = double(y2-y1)/steps;
|
||||||
|
for (int i=0;i<steps;i++) {
|
||||||
|
if (i % 2 == 0) DrawLine(x1+int(i*stepx),y1+int(i*stepy),x1+int((i+1)*stepx),y1+int((i+1)*stepy));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Draw circle
|
// Draw circle
|
||||||
void OpenGLWrapper::DrawEllipse(float x,float y,float radiusX,float radiusY) {
|
void OpenGLWrapper::DrawEllipse(float x,float y,float radiusX,float radiusY) {
|
||||||
|
|
|
@ -60,6 +60,7 @@ public:
|
||||||
void SetModeLine();
|
void SetModeLine();
|
||||||
void SetModeFill();
|
void SetModeFill();
|
||||||
void DrawLine(float x1,float y1,float x2,float y2);
|
void DrawLine(float x1,float y1,float x2,float y2);
|
||||||
|
void DrawDashedLine(float x1,float y1,float x2,float y2,float dashLen);
|
||||||
void DrawEllipse(float x,float y,float radiusX,float radiusY);
|
void DrawEllipse(float x,float y,float radiusX,float radiusY);
|
||||||
void DrawCircle(float x,float y,float radius) { DrawEllipse(x,y,radius,radius); }
|
void DrawCircle(float x,float y,float radius) { DrawEllipse(x,y,radius,radius); }
|
||||||
void DrawRectangle(float x1,float y1,float x2,float y2);
|
void DrawRectangle(float x1,float y1,float x2,float y2);
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
|
|
||||||
///////////
|
///////////
|
||||||
// Headers
|
// Headers
|
||||||
|
#include <wx/tokenzr.h>
|
||||||
#include "spline.h"
|
#include "spline.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -63,10 +64,10 @@ wxString Spline::EncodeToASS() {
|
||||||
bool isFirst = true;
|
bool isFirst = true;
|
||||||
|
|
||||||
// Insert each element
|
// Insert each element
|
||||||
for (std::list<SplineCurve>::iterator cur = curves.begin();cur!=curves.end();cur++) {
|
for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end();cur++) {
|
||||||
// Start of spline
|
// Start of spline
|
||||||
if (isFirst) {
|
if (isFirst) {
|
||||||
result = wxString::Format(_T("m %i %i"),cur->x1,cur->y1);
|
result = wxString::Format(_T("m %i %i "),cur->x1,cur->y1);
|
||||||
lastCommand = 'm';
|
lastCommand = 'm';
|
||||||
isFirst = false;
|
isFirst = false;
|
||||||
}
|
}
|
||||||
|
@ -78,14 +79,14 @@ wxString Spline::EncodeToASS() {
|
||||||
result += _T("l ");
|
result += _T("l ");
|
||||||
lastCommand = 'l';
|
lastCommand = 'l';
|
||||||
}
|
}
|
||||||
result += wxString::Format(_T("%i %i"),cur->x2,cur->y2);
|
result += wxString::Format(_T("%i %i "),cur->x2,cur->y2);
|
||||||
break;
|
break;
|
||||||
case CURVE_BICUBIC:
|
case CURVE_BICUBIC:
|
||||||
if (lastCommand != 'b') {
|
if (lastCommand != 'b') {
|
||||||
result += _T("b ");
|
result += _T("b ");
|
||||||
lastCommand = 'b';
|
lastCommand = 'b';
|
||||||
}
|
}
|
||||||
result += wxString::Format(_T("%i %i %i %i"),cur->x2,cur->y2,cur->x3,cur->y3,cur->x4,cur->y4);
|
result += wxString::Format(_T("%i %i %i %i %i %i "),cur->x2,cur->y2,cur->x3,cur->y3,cur->x4,cur->y4);
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
@ -99,6 +100,79 @@ wxString Spline::EncodeToASS() {
|
||||||
void Spline::DecodeFromASS(wxString str) {
|
void Spline::DecodeFromASS(wxString str) {
|
||||||
// Clear current
|
// Clear current
|
||||||
curves.clear();
|
curves.clear();
|
||||||
|
std::vector<int> stack;
|
||||||
|
|
||||||
|
// Prepare
|
||||||
|
char lastCommand = 'm';
|
||||||
|
int x = 0;
|
||||||
|
int y = 0;
|
||||||
|
|
||||||
|
// Tokenize the string
|
||||||
|
wxStringTokenizer tkn(str,_T(" "));
|
||||||
|
while (tkn.HasMoreTokens()) {
|
||||||
|
wxString token = tkn.GetNextToken();
|
||||||
|
|
||||||
|
// Got a number
|
||||||
|
if (token.IsNumber()) {
|
||||||
|
long n;
|
||||||
|
token.ToLong(&n);
|
||||||
|
stack.push_back(n);
|
||||||
|
|
||||||
|
// Move
|
||||||
|
if (stack.size() == 2 && lastCommand == 'm') {
|
||||||
|
x = stack[0];
|
||||||
|
y = stack[1];
|
||||||
|
stack.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line
|
||||||
|
if (stack.size() == 2 && lastCommand == 'l') {
|
||||||
|
SplineCurve curve;
|
||||||
|
curve.x1 = x;
|
||||||
|
curve.y1 = y;
|
||||||
|
curve.x2 = stack[0];
|
||||||
|
curve.y2 = stack[1];
|
||||||
|
curve.type = CURVE_LINE;
|
||||||
|
x = curve.x2;
|
||||||
|
y = curve.y2;
|
||||||
|
stack.clear();
|
||||||
|
AppendCurve(curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bicubic
|
||||||
|
else if (stack.size() == 6 && lastCommand == 'b') {
|
||||||
|
SplineCurve curve;
|
||||||
|
curve.x1 = x;
|
||||||
|
curve.y1 = y;
|
||||||
|
curve.x2 = stack[0];
|
||||||
|
curve.y2 = stack[1];
|
||||||
|
curve.x3 = stack[2];
|
||||||
|
curve.y3 = stack[3];
|
||||||
|
curve.x4 = stack[4];
|
||||||
|
curve.y4 = stack[5];
|
||||||
|
curve.type = CURVE_BICUBIC;
|
||||||
|
x = curve.x4;
|
||||||
|
y = curve.y4;
|
||||||
|
stack.clear();
|
||||||
|
AppendCurve(curve);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close
|
||||||
|
else if (lastCommand == 'c') {
|
||||||
|
stack.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Got something else
|
||||||
|
else {
|
||||||
|
if (token == _T("m")) lastCommand = 'm';
|
||||||
|
else if (token == _T("l")) lastCommand = 'l';
|
||||||
|
else if (token == _T("b")) lastCommand = 'b';
|
||||||
|
else if (token == _T("n")) lastCommand = 'n';
|
||||||
|
else if (token == _T("s")) lastCommand = 's';
|
||||||
|
else if (token == _T("c")) lastCommand = 'c';
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,31 +186,63 @@ void Spline::AppendCurve(SplineCurve &curve) {
|
||||||
////////////////////////////////////////
|
////////////////////////////////////////
|
||||||
// Moves a specific point in the spline
|
// Moves a specific point in the spline
|
||||||
void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
|
void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
|
||||||
|
// Curves
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
SplineCurve *c0 = NULL;
|
||||||
|
SplineCurve *c1 = NULL;
|
||||||
|
SplineCurve *c2 = NULL;
|
||||||
|
|
||||||
|
// Indices
|
||||||
|
int size = curves.size();
|
||||||
|
int i0 = curveIndex-1;
|
||||||
|
int i1 = curveIndex;
|
||||||
|
int i2 = curveIndex+1;
|
||||||
|
//if (i0 < 0) i0 = size-1;
|
||||||
|
//if (i2 >= size) i2 = 0;
|
||||||
|
|
||||||
|
// Get the curves
|
||||||
for (std::list<SplineCurve>::iterator cur = curves.begin();cur!=curves.end();cur++) {
|
for (std::list<SplineCurve>::iterator cur = curves.begin();cur!=curves.end();cur++) {
|
||||||
if (i == curveIndex) {
|
if (i == i0) c0 = &(*cur);
|
||||||
switch (point) {
|
if (i == i1) c1 = &(*cur);
|
||||||
case 0:
|
if (i == i2) c2 = &(*cur);
|
||||||
cur->x1 = pos.x;
|
|
||||||
cur->y1 = pos.y;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
cur->x2 = pos.x;
|
|
||||||
cur->y2 = pos.y;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
cur->x3 = pos.x;
|
|
||||||
cur->y3 = pos.y;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
cur->x4 = pos.x;
|
|
||||||
cur->y4 = pos.y;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Modify
|
||||||
|
if (point == 0) {
|
||||||
|
c1->x1 = pos.x;
|
||||||
|
c1->y1 = pos.y;
|
||||||
|
if (c0) {
|
||||||
|
if (c0->type == CURVE_BICUBIC) {
|
||||||
|
c0->x4 = pos.x;
|
||||||
|
c0->y4 = pos.y;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
c0->x2 = pos.x;
|
||||||
|
c0->y2 = pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (point == 1) {
|
||||||
|
c1->x2 = pos.x;
|
||||||
|
c1->y2 = pos.y;
|
||||||
|
if (c2 && c1->type != CURVE_BICUBIC) {
|
||||||
|
c2->x1 = pos.x;
|
||||||
|
c2->y1 = pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (point == 2) {
|
||||||
|
c1->x3 = pos.x;
|
||||||
|
c1->y3 = pos.y;
|
||||||
|
}
|
||||||
|
else if (point == 3) {
|
||||||
|
c1->x4 = pos.x;
|
||||||
|
c1->y4 = pos.y;
|
||||||
|
if (c2 && c1->type == CURVE_BICUBIC) {
|
||||||
|
c2->x1 = pos.x;
|
||||||
|
c2->y1 = pos.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -176,8 +282,8 @@ void Spline::GetPointList(std::vector<wxPoint> &points) {
|
||||||
int y3 = cur->y3;
|
int y3 = cur->y3;
|
||||||
int y4 = cur->y4;
|
int y4 = cur->y4;
|
||||||
|
|
||||||
// Hardcoded at 10 steps for now
|
// Hardcoded at 50 steps for now
|
||||||
int steps = 10;
|
int steps = 50;
|
||||||
for (int i=0;i<steps;i++) {
|
for (int i=0;i<steps;i++) {
|
||||||
// Get t and t-1 (u)
|
// Get t and t-1 (u)
|
||||||
float t = float(i)/float(steps);
|
float t = float(i)/float(steps);
|
||||||
|
@ -190,6 +296,11 @@ void Spline::GetPointList(std::vector<wxPoint> &points) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Insert a copy of the first point at the end
|
||||||
|
if (points.size()) {
|
||||||
|
points.push_back(points[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,10 +71,9 @@ public:
|
||||||
/////////////////////////
|
/////////////////////////
|
||||||
// Spline managing class
|
// Spline managing class
|
||||||
class Spline {
|
class Spline {
|
||||||
private:
|
public:
|
||||||
std::list<SplineCurve> curves;
|
std::list<SplineCurve> curves;
|
||||||
|
|
||||||
public:
|
|
||||||
Spline();
|
Spline();
|
||||||
|
|
||||||
wxString EncodeToASS();
|
wxString EncodeToASS();
|
||||||
|
|
|
@ -118,6 +118,8 @@ VideoBox::VideoBox(wxWindow *parent)
|
||||||
scale->SetToolTip(_("Scale subtitles on X and Y axes."));
|
scale->SetToolTip(_("Scale subtitles on X and Y axes."));
|
||||||
clip = new wxBitmapButton(videoPage,Video_Mode_Clip,wxBITMAP(visual_clip));
|
clip = new wxBitmapButton(videoPage,Video_Mode_Clip,wxBITMAP(visual_clip));
|
||||||
clip->SetToolTip(_("Clip subtitles to a rectangle."));
|
clip->SetToolTip(_("Clip subtitles to a rectangle."));
|
||||||
|
vectorClip = new wxBitmapButton(videoPage,Video_Mode_Vector_Clip,wxBITMAP(visual_clip));
|
||||||
|
vectorClip->SetToolTip(_("Clip subtitles to a vectorial area."));
|
||||||
realtime = new ToggleBitmap(videoPage,Video_Mode_Realtime,wxBITMAP(visual_realtime),wxSize(20,20));
|
realtime = new ToggleBitmap(videoPage,Video_Mode_Realtime,wxBITMAP(visual_realtime),wxSize(20,20));
|
||||||
realtime->SetToolTip(_("Toggle realtime display of changes."));
|
realtime->SetToolTip(_("Toggle realtime display of changes."));
|
||||||
bool isRealtime = Options.AsBool(_T("Video Visual Realtime"));
|
bool isRealtime = Options.AsBool(_T("Video Visual Realtime"));
|
||||||
|
@ -128,7 +130,8 @@ VideoBox::VideoBox(wxWindow *parent)
|
||||||
typeSizer->Add(rotatez,0,wxEXPAND,0);
|
typeSizer->Add(rotatez,0,wxEXPAND,0);
|
||||||
typeSizer->Add(rotatexy,0,wxEXPAND,0);
|
typeSizer->Add(rotatexy,0,wxEXPAND,0);
|
||||||
typeSizer->Add(scale,0,wxEXPAND,0);
|
typeSizer->Add(scale,0,wxEXPAND,0);
|
||||||
typeSizer->Add(clip,0,wxEXPAND | wxBOTTOM,5);
|
typeSizer->Add(clip,0,wxEXPAND,0);
|
||||||
|
typeSizer->Add(vectorClip,0,wxEXPAND | wxBOTTOM,5);
|
||||||
typeSizer->Add(realtime,0,wxEXPAND,0);
|
typeSizer->Add(realtime,0,wxEXPAND,0);
|
||||||
typeSizer->AddStretchSpacer(1);
|
typeSizer->AddStretchSpacer(1);
|
||||||
|
|
||||||
|
@ -175,6 +178,7 @@ BEGIN_EVENT_TABLE(VideoBox, wxPanel)
|
||||||
EVT_BUTTON(Video_Mode_Rotate_XY, VideoBox::OnModeRotateXY)
|
EVT_BUTTON(Video_Mode_Rotate_XY, VideoBox::OnModeRotateXY)
|
||||||
EVT_BUTTON(Video_Mode_Scale, VideoBox::OnModeScale)
|
EVT_BUTTON(Video_Mode_Scale, VideoBox::OnModeScale)
|
||||||
EVT_BUTTON(Video_Mode_Clip, VideoBox::OnModeClip)
|
EVT_BUTTON(Video_Mode_Clip, VideoBox::OnModeClip)
|
||||||
|
EVT_BUTTON(Video_Mode_Vector_Clip, VideoBox::OnModeVectorClip)
|
||||||
EVT_TOGGLEBUTTON(Video_Mode_Realtime, VideoBox::OnToggleRealtime)
|
EVT_TOGGLEBUTTON(Video_Mode_Realtime, VideoBox::OnToggleRealtime)
|
||||||
END_EVENT_TABLE()
|
END_EVENT_TABLE()
|
||||||
|
|
||||||
|
@ -254,6 +258,13 @@ void VideoBox::OnModeClip(wxCommandEvent &event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////
|
||||||
|
// Vector clip mode
|
||||||
|
void VideoBox::OnModeVectorClip(wxCommandEvent &event) {
|
||||||
|
videoDisplay->SetVisualMode(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
///////////////////
|
///////////////////
|
||||||
// Realtime toggle
|
// Realtime toggle
|
||||||
void VideoBox::OnToggleRealtime(wxCommandEvent &event) {
|
void VideoBox::OnToggleRealtime(wxCommandEvent &event) {
|
||||||
|
|
|
@ -62,6 +62,7 @@ private:
|
||||||
wxButton *rotatexy;
|
wxButton *rotatexy;
|
||||||
wxButton *scale;
|
wxButton *scale;
|
||||||
wxButton *clip;
|
wxButton *clip;
|
||||||
|
wxButton *vectorClip;
|
||||||
ToggleBitmap *realtime;
|
ToggleBitmap *realtime;
|
||||||
|
|
||||||
void OnVideoPlay(wxCommandEvent &event);
|
void OnVideoPlay(wxCommandEvent &event);
|
||||||
|
@ -79,6 +80,7 @@ private:
|
||||||
void OnModeRotateXY(wxCommandEvent &event);
|
void OnModeRotateXY(wxCommandEvent &event);
|
||||||
void OnModeScale(wxCommandEvent &event);
|
void OnModeScale(wxCommandEvent &event);
|
||||||
void OnModeClip(wxCommandEvent &event);
|
void OnModeClip(wxCommandEvent &event);
|
||||||
|
void OnModeVectorClip(wxCommandEvent &event);
|
||||||
void OnToggleRealtime(wxCommandEvent &event);
|
void OnToggleRealtime(wxCommandEvent &event);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -113,6 +115,7 @@ enum {
|
||||||
Video_Mode_Rotate_XY,
|
Video_Mode_Rotate_XY,
|
||||||
Video_Mode_Scale,
|
Video_Mode_Scale,
|
||||||
Video_Mode_Clip,
|
Video_Mode_Clip,
|
||||||
|
Video_Mode_Vector_Clip,
|
||||||
Video_Mode_Realtime,
|
Video_Mode_Realtime,
|
||||||
|
|
||||||
Video_Tracker_Menu,
|
Video_Tracker_Menu,
|
||||||
|
|
|
@ -73,6 +73,7 @@
|
||||||
#include "visual_tool_rotatexy.h"
|
#include "visual_tool_rotatexy.h"
|
||||||
#include "visual_tool_scale.h"
|
#include "visual_tool_scale.h"
|
||||||
#include "visual_tool_clip.h"
|
#include "visual_tool_clip.h"
|
||||||
|
#include "visual_tool_vector_clip.h"
|
||||||
#include "visual_tool_drag.h"
|
#include "visual_tool_drag.h"
|
||||||
|
|
||||||
|
|
||||||
|
@ -106,7 +107,7 @@ END_EVENT_TABLE()
|
||||||
|
|
||||||
//////////////
|
//////////////
|
||||||
// Parameters
|
// Parameters
|
||||||
int attribList[3] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER, 0 };
|
int attribList[] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER, WX_GL_STENCIL_SIZE, 8, 0 };
|
||||||
|
|
||||||
///////////////
|
///////////////
|
||||||
// Constructor
|
// Constructor
|
||||||
|
@ -185,18 +186,20 @@ void VideoDisplay::Render() {
|
||||||
wxASSERT(pw > 0);
|
wxASSERT(pw > 0);
|
||||||
wxASSERT(ph > 0);
|
wxASSERT(ph > 0);
|
||||||
|
|
||||||
|
// Clear frame buffer
|
||||||
|
glClearColor(0,0,0,0);
|
||||||
|
if (glGetError()) throw _T("Error setting glClearColor().");
|
||||||
|
glClearStencil(0);
|
||||||
|
if (glGetError()) throw _T("Error setting glClearStencil().");
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
|
||||||
|
if (glGetError()) throw _T("Error calling glClear().");
|
||||||
|
|
||||||
// Freesized transform
|
// Freesized transform
|
||||||
dx1 = 0;
|
dx1 = 0;
|
||||||
dy1 = 0;
|
dy1 = 0;
|
||||||
dx2 = w;
|
dx2 = w;
|
||||||
dy2 = h;
|
dy2 = h;
|
||||||
if (freeSize) {
|
if (freeSize) {
|
||||||
// Clear frame buffer
|
|
||||||
glClearColor(0,0,0,0);
|
|
||||||
if (glGetError()) throw _T("Error setting glClearColor().");
|
|
||||||
glClear(GL_COLOR_BUFFER_BIT);
|
|
||||||
if (glGetError()) throw _T("Error calling glClear().");
|
|
||||||
|
|
||||||
// Set aspect ratio
|
// Set aspect ratio
|
||||||
float thisAr = float(w)/float(h);
|
float thisAr = float(w)/float(h);
|
||||||
float vidAr;
|
float vidAr;
|
||||||
|
@ -482,7 +485,8 @@ void VideoDisplay::OnKey(wxKeyEvent &event) {
|
||||||
if (event.GetKeyCode() == 'D') SetVisualMode(2);
|
if (event.GetKeyCode() == 'D') SetVisualMode(2);
|
||||||
if (event.GetKeyCode() == 'F') SetVisualMode(3);
|
if (event.GetKeyCode() == 'F') SetVisualMode(3);
|
||||||
if (event.GetKeyCode() == 'G') SetVisualMode(4);
|
if (event.GetKeyCode() == 'G') SetVisualMode(4);
|
||||||
if (event.GetKeyCode() == 'H') SetVisualMode(5);
|
if (event.GetKeyCode() == 'H') SetVisualMode(5);
|
||||||
|
if (event.GetKeyCode() == 'J') SetVisualMode(6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -664,6 +668,7 @@ void VideoDisplay::SetVisualMode(int mode) {
|
||||||
case 3: visual = new VisualToolRotateXY(this); break;
|
case 3: visual = new VisualToolRotateXY(this); break;
|
||||||
case 4: visual = new VisualToolScale(this); break;
|
case 4: visual = new VisualToolScale(this); break;
|
||||||
case 5: visual = new VisualToolClip(this); break;
|
case 5: visual = new VisualToolClip(this); break;
|
||||||
|
case 6: visual = new VisualToolVectorClip(this); break;
|
||||||
default: visual = NULL;
|
default: visual = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ VisualDraggableFeature::VisualDraggableFeature() {
|
||||||
type = DRAG_NONE;
|
type = DRAG_NONE;
|
||||||
x = -1;
|
x = -1;
|
||||||
y = -1;
|
y = -1;
|
||||||
value = 0;
|
value = value2 = 0;
|
||||||
layer = 0;
|
layer = 0;
|
||||||
lineN = -1;
|
lineN = -1;
|
||||||
line = NULL;
|
line = NULL;
|
||||||
|
@ -80,6 +80,12 @@ bool VisualDraggableFeature::IsMouseOver(int mx,int my) {
|
||||||
return (16*dx+9*dy < 0 && 16*dx-9*dy > 0);
|
return (16*dx+9*dy < 0 && 16*dx-9*dy > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Small square
|
||||||
|
else if (type == DRAG_SMALL_SQUARE) {
|
||||||
|
if (mx < x-4 || mx > x+4 || my < y-4 || my > y+4) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Small circle
|
// Small circle
|
||||||
else if (type == DRAG_SMALL_CIRCLE) {
|
else if (type == DRAG_SMALL_CIRCLE) {
|
||||||
int dx = mx-x;
|
int dx = mx-x;
|
||||||
|
@ -120,6 +126,11 @@ void VisualDraggableFeature::Draw(OpenGLWrapper *gl) {
|
||||||
gl->DrawLine(x,y,x+14,y+8);
|
gl->DrawLine(x,y,x+14,y+8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Square
|
||||||
|
else if (type == DRAG_SMALL_SQUARE) {
|
||||||
|
gl->DrawRectangle(x-4,y-4,x+4,y+4);
|
||||||
|
}
|
||||||
|
|
||||||
// Small circle
|
// Small circle
|
||||||
else if (type == DRAG_SMALL_CIRCLE) {
|
else if (type == DRAG_SMALL_CIRCLE) {
|
||||||
gl->DrawCircle(x,y,4);
|
gl->DrawCircle(x,y,4);
|
||||||
|
|
|
@ -66,7 +66,7 @@ public:
|
||||||
DraggableFeatureType type;
|
DraggableFeatureType type;
|
||||||
int x,y;
|
int x,y;
|
||||||
int layer; // Higher = above
|
int layer; // Higher = above
|
||||||
int value;
|
int value,value2;
|
||||||
|
|
||||||
AssDialogue *line;
|
AssDialogue *line;
|
||||||
int lineN;
|
int lineN;
|
||||||
|
|
|
@ -581,6 +581,42 @@ 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) {
|
||||||
|
// Prepare overrides
|
||||||
|
wxString result;
|
||||||
|
scale = 1;
|
||||||
|
diag->ParseASSTags();
|
||||||
|
AssDialogueBlockOverride *override;
|
||||||
|
AssOverrideTag *tag;
|
||||||
|
size_t blockn = diag->Blocks.size();
|
||||||
|
if (blockn == 0) {
|
||||||
|
diag->ClearBlocks();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process override
|
||||||
|
override = AssDialogueBlock::GetAsOverride(diag->Blocks.at(0));
|
||||||
|
if (override) {
|
||||||
|
for (size_t j=0;j<override->Tags.size();j++) {
|
||||||
|
tag = override->Tags.at(j);
|
||||||
|
if (tag->Name == _T("\\clip")) {
|
||||||
|
if (tag->Params.size() == 1) {
|
||||||
|
result = tag->Params[0]->AsText();
|
||||||
|
}
|
||||||
|
if (tag->Params.size() == 2) {
|
||||||
|
scale = tag->Params[0]->AsInt();
|
||||||
|
result = tag->Params[1]->AsText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diag->ClearBlocks();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
// Set override
|
// Set override
|
||||||
void VisualTool::SetOverride(wxString tag,wxString value) {
|
void VisualTool::SetOverride(wxString tag,wxString value) {
|
||||||
|
|
|
@ -101,6 +101,7 @@ protected:
|
||||||
void GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz);
|
void GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz);
|
||||||
void GetLineScale(AssDialogue *diag,float &scalX,float &scalY);
|
void GetLineScale(AssDialogue *diag,float &scalX,float &scalY);
|
||||||
void GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2);
|
void GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2);
|
||||||
|
wxString GetLineVectorClip(AssDialogue *diag,int &scale);
|
||||||
void FillPositionData();
|
void FillPositionData();
|
||||||
void SetOverride(wxString tag,wxString value);
|
void SetOverride(wxString tag,wxString value);
|
||||||
|
|
||||||
|
|
|
@ -92,7 +92,7 @@ void VisualToolClip::Draw() {
|
||||||
|
|
||||||
// Draw outside area
|
// Draw outside area
|
||||||
SetLineColour(colour[3],0.0f);
|
SetLineColour(colour[3],0.0f);
|
||||||
SetFillColour(colour[3],0.3f);
|
SetFillColour(wxColour(0,0,0),0.5f);
|
||||||
DrawRectangle(0,0,sw,dy1);
|
DrawRectangle(0,0,sw,dy1);
|
||||||
DrawRectangle(0,dy2,sw,sh);
|
DrawRectangle(0,dy2,sw,sh);
|
||||||
DrawRectangle(0,dy1,dx1,dy2);
|
DrawRectangle(0,dy1,dx1,dy2);
|
||||||
|
|
|
@ -185,12 +185,7 @@ void VisualToolDrag::Draw() {
|
||||||
// Draw dashed line
|
// Draw dashed line
|
||||||
else {
|
else {
|
||||||
SetLineColour(colour[3],0.5f,2);
|
SetLineColour(colour[3],0.5f,2);
|
||||||
int steps = (dist-20)/6;
|
DrawDashedLine(x1,y1,x2,y2,6);
|
||||||
double stepx = double(x2-x1)/steps;
|
|
||||||
double stepy = double(y2-y1)/steps;
|
|
||||||
for (int i=0;i<steps;i++) {
|
|
||||||
if (i % 2 == 0) DrawLine(x1+int(i*stepx),y1+int(i*stepy),x1+int((i+1)*stepx),y1+int((i+1)*stepy));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,204 @@
|
||||||
|
// Copyright (c) 2007, 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
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:zeratul@cellosoft.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include "visual_tool_vector_clip.h"
|
||||||
|
#include "ass_dialogue.h"
|
||||||
|
|
||||||
|
|
||||||
|
///////////////
|
||||||
|
// Constructor
|
||||||
|
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent)
|
||||||
|
: VisualTool(parent)
|
||||||
|
{
|
||||||
|
DoRefresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// Update
|
||||||
|
void VisualToolVectorClip::Update() {
|
||||||
|
GetParent()->Render();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////
|
||||||
|
// Draw
|
||||||
|
void VisualToolVectorClip::Draw() {
|
||||||
|
// Get line
|
||||||
|
AssDialogue *line = GetActiveDialogueLine();
|
||||||
|
if (!line) return;
|
||||||
|
|
||||||
|
// Parse vector
|
||||||
|
std::vector<wxPoint> points;
|
||||||
|
spline.GetPointList(points);
|
||||||
|
|
||||||
|
// Draw lines
|
||||||
|
SetLineColour(colour[3]);
|
||||||
|
SetFillColour(colour[3],0.0f);
|
||||||
|
for (size_t i=0;i<points.size()-1;i++) {
|
||||||
|
DrawLine(points[i].x,points[i].y,points[i+1].x,points[i+1].y);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw stencil mask
|
||||||
|
glEnable(GL_STENCIL_TEST);
|
||||||
|
glColorMask(0,0,0,0);
|
||||||
|
glStencilFunc(GL_NEVER,1,1);
|
||||||
|
glStencilOp(GL_INVERT,GL_INVERT,GL_INVERT);
|
||||||
|
for (size_t i=1;i<points.size()-1;i++) {
|
||||||
|
glBegin(GL_TRIANGLES);
|
||||||
|
glVertex2f(points[0].x,points[0].y);
|
||||||
|
glVertex2f(points[i].x,points[i].y);
|
||||||
|
glVertex2f(points[i+1].x,points[i+1].y);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw "outside clip" mask
|
||||||
|
glColorMask(1,1,1,1);
|
||||||
|
glStencilFunc(GL_EQUAL, 0, 1);
|
||||||
|
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
|
||||||
|
SetFillColour(wxColour(0,0,0),0.5f);
|
||||||
|
DrawRectangle(0,0,sw,sh);
|
||||||
|
glDisable(GL_STENCIL_TEST);
|
||||||
|
|
||||||
|
// Draw features
|
||||||
|
DrawAllFeatures();
|
||||||
|
|
||||||
|
// Draw lines connecting the bicubic features
|
||||||
|
SetLineColour(colour[3],0.9f,1);
|
||||||
|
for (std::list<SplineCurve>::iterator cur=spline.curves.begin();cur!=spline.curves.end();cur++) {
|
||||||
|
if (cur->type == CURVE_BICUBIC) {
|
||||||
|
DrawDashedLine(cur->x1,cur->y1,cur->x2,cur->y2,6);
|
||||||
|
DrawDashedLine(cur->x3,cur->y3,cur->x4,cur->y4,6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////
|
||||||
|
// Populate feature list
|
||||||
|
void VisualToolVectorClip::PopulateFeatureList() {
|
||||||
|
// Clear
|
||||||
|
features.clear();
|
||||||
|
VisualDraggableFeature feat;
|
||||||
|
|
||||||
|
// Go through each curve
|
||||||
|
bool isFirst = true;
|
||||||
|
int i = 0;
|
||||||
|
for (std::list<SplineCurve>::iterator cur=spline.curves.begin();cur!=spline.curves.end();cur++,i++) {
|
||||||
|
// First point
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
feat.x = cur->x1;
|
||||||
|
feat.y = cur->y1;
|
||||||
|
feat.type = DRAG_SMALL_CIRCLE;
|
||||||
|
feat.value = i;
|
||||||
|
feat.value2 = 0;
|
||||||
|
features.push_back(feat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Line
|
||||||
|
if (cur->type == CURVE_LINE) {
|
||||||
|
feat.x = cur->x2;
|
||||||
|
feat.y = cur->y2;
|
||||||
|
feat.type = DRAG_SMALL_CIRCLE;
|
||||||
|
feat.value = i;
|
||||||
|
feat.value2 = 1;
|
||||||
|
features.push_back(feat);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bicubic
|
||||||
|
if (cur->type == CURVE_BICUBIC) {
|
||||||
|
// Current size
|
||||||
|
int size = features.size();
|
||||||
|
|
||||||
|
// Control points
|
||||||
|
feat.x = cur->x2;
|
||||||
|
feat.y = cur->y2;
|
||||||
|
feat.value = i;
|
||||||
|
feat.value2 = 1;
|
||||||
|
feat.brother[0] = size-1;
|
||||||
|
feat.type = DRAG_SMALL_SQUARE;
|
||||||
|
features.push_back(feat);
|
||||||
|
feat.x = cur->x3;
|
||||||
|
feat.y = cur->y3;
|
||||||
|
feat.value2 = 2;
|
||||||
|
feat.brother[0] = size+2;
|
||||||
|
features.push_back(feat);
|
||||||
|
|
||||||
|
// End point
|
||||||
|
feat.x = cur->x4;
|
||||||
|
feat.y = cur->y4;
|
||||||
|
feat.type = DRAG_SMALL_CIRCLE;
|
||||||
|
feat.value2 = 3;
|
||||||
|
features.push_back(feat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// Update
|
||||||
|
void VisualToolVectorClip::UpdateDrag(VisualDraggableFeature &feature) {
|
||||||
|
spline.MovePoint(feature.value,feature.value2,wxPoint(feature.x,feature.y));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////
|
||||||
|
// Commit
|
||||||
|
void VisualToolVectorClip::CommitDrag(VisualDraggableFeature &feature) {
|
||||||
|
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Refresh
|
||||||
|
void VisualToolVectorClip::DoRefresh() {
|
||||||
|
if (!dragging) {
|
||||||
|
// Get line
|
||||||
|
AssDialogue *line = GetActiveDialogueLine();
|
||||||
|
if (!line) return;
|
||||||
|
|
||||||
|
// Get clip vector
|
||||||
|
wxString vect;
|
||||||
|
int scale;
|
||||||
|
vect = GetLineVectorClip(line,scale);
|
||||||
|
if (vect.IsEmpty()) return;
|
||||||
|
spline.DecodeFromASS(vect);
|
||||||
|
PopulateFeatureList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
// Copyright (c) 2007, 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
|
||||||
|
//
|
||||||
|
// Website: http://aegisub.cellosoft.com
|
||||||
|
// Contact: mailto:zeratul@cellosoft.com
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
|
||||||
|
///////////
|
||||||
|
// Headers
|
||||||
|
#include "visual_tool.h"
|
||||||
|
#include "spline.h"
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////
|
||||||
|
// Vector clip tool class
|
||||||
|
class VisualToolVectorClip : public VisualTool {
|
||||||
|
private:
|
||||||
|
Spline spline;
|
||||||
|
|
||||||
|
bool CanDrag() { return true; }
|
||||||
|
void PopulateFeatureList();
|
||||||
|
void UpdateDrag(VisualDraggableFeature &feature);
|
||||||
|
void CommitDrag(VisualDraggableFeature &feature);
|
||||||
|
|
||||||
|
void DoRefresh();
|
||||||
|
|
||||||
|
public:
|
||||||
|
VisualToolVectorClip(VideoDisplay *parent);
|
||||||
|
|
||||||
|
void Update();
|
||||||
|
void Draw();
|
||||||
|
};
|
Loading…
Reference in New Issue