Barely function vector clip tool implemented
Originally committed to SVN as r1364.
This commit is contained in:
parent
5e25ffe30b
commit
570321722b
16 changed files with 502 additions and 47 deletions
|
@ -222,6 +222,7 @@ aegisub_SOURCES = \
|
|||
visual_tool_rotatexy.cpp \
|
||||
visual_tool_rotatez.cpp \
|
||||
visual_tool_scale.cpp \
|
||||
visual_tool_vector_clip.cpp \
|
||||
MatroskaParser.c
|
||||
|
||||
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
|
||||
void OpenGLWrapper::DrawEllipse(float x,float y,float radiusX,float radiusY) {
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
void SetModeLine();
|
||||
void SetModeFill();
|
||||
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 DrawCircle(float x,float y,float radius) { DrawEllipse(x,y,radius,radius); }
|
||||
void DrawRectangle(float x1,float y1,float x2,float y2);
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
///////////
|
||||
// Headers
|
||||
#include <wx/tokenzr.h>
|
||||
#include "spline.h"
|
||||
|
||||
|
||||
|
@ -63,10 +64,10 @@ wxString Spline::EncodeToASS() {
|
|||
bool isFirst = true;
|
||||
|
||||
// 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
|
||||
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';
|
||||
isFirst = false;
|
||||
}
|
||||
|
@ -78,14 +79,14 @@ wxString Spline::EncodeToASS() {
|
|||
result += _T("l ");
|
||||
lastCommand = 'l';
|
||||
}
|
||||
result += wxString::Format(_T("%i %i"),cur->x2,cur->y2);
|
||||
result += wxString::Format(_T("%i %i "),cur->x2,cur->y2);
|
||||
break;
|
||||
case CURVE_BICUBIC:
|
||||
if (lastCommand != 'b') {
|
||||
result += _T("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;
|
||||
default: break;
|
||||
}
|
||||
|
@ -99,6 +100,79 @@ wxString Spline::EncodeToASS() {
|
|||
void Spline::DecodeFromASS(wxString str) {
|
||||
// Clear current
|
||||
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
|
||||
void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
|
||||
// Curves
|
||||
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++) {
|
||||
if (i == curveIndex) {
|
||||
switch (point) {
|
||||
case 0:
|
||||
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;
|
||||
}
|
||||
if (i == i0) c0 = &(*cur);
|
||||
if (i == i1) c1 = &(*cur);
|
||||
if (i == i2) c2 = &(*cur);
|
||||
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 y4 = cur->y4;
|
||||
|
||||
// Hardcoded at 10 steps for now
|
||||
int steps = 10;
|
||||
// Hardcoded at 50 steps for now
|
||||
int steps = 50;
|
||||
for (int i=0;i<steps;i++) {
|
||||
// Get t and t-1 (u)
|
||||
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
|
||||
class Spline {
|
||||
private:
|
||||
public:
|
||||
std::list<SplineCurve> curves;
|
||||
|
||||
public:
|
||||
Spline();
|
||||
|
||||
wxString EncodeToASS();
|
||||
|
|
|
@ -118,6 +118,8 @@ VideoBox::VideoBox(wxWindow *parent)
|
|||
scale->SetToolTip(_("Scale subtitles on X and Y axes."));
|
||||
clip = new wxBitmapButton(videoPage,Video_Mode_Clip,wxBITMAP(visual_clip));
|
||||
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->SetToolTip(_("Toggle realtime display of changes."));
|
||||
bool isRealtime = Options.AsBool(_T("Video Visual Realtime"));
|
||||
|
@ -128,7 +130,8 @@ VideoBox::VideoBox(wxWindow *parent)
|
|||
typeSizer->Add(rotatez,0,wxEXPAND,0);
|
||||
typeSizer->Add(rotatexy,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->AddStretchSpacer(1);
|
||||
|
||||
|
@ -175,6 +178,7 @@ BEGIN_EVENT_TABLE(VideoBox, wxPanel)
|
|||
EVT_BUTTON(Video_Mode_Rotate_XY, VideoBox::OnModeRotateXY)
|
||||
EVT_BUTTON(Video_Mode_Scale, VideoBox::OnModeScale)
|
||||
EVT_BUTTON(Video_Mode_Clip, VideoBox::OnModeClip)
|
||||
EVT_BUTTON(Video_Mode_Vector_Clip, VideoBox::OnModeVectorClip)
|
||||
EVT_TOGGLEBUTTON(Video_Mode_Realtime, VideoBox::OnToggleRealtime)
|
||||
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
|
||||
void VideoBox::OnToggleRealtime(wxCommandEvent &event) {
|
||||
|
|
|
@ -62,6 +62,7 @@ private:
|
|||
wxButton *rotatexy;
|
||||
wxButton *scale;
|
||||
wxButton *clip;
|
||||
wxButton *vectorClip;
|
||||
ToggleBitmap *realtime;
|
||||
|
||||
void OnVideoPlay(wxCommandEvent &event);
|
||||
|
@ -79,6 +80,7 @@ private:
|
|||
void OnModeRotateXY(wxCommandEvent &event);
|
||||
void OnModeScale(wxCommandEvent &event);
|
||||
void OnModeClip(wxCommandEvent &event);
|
||||
void OnModeVectorClip(wxCommandEvent &event);
|
||||
void OnToggleRealtime(wxCommandEvent &event);
|
||||
|
||||
public:
|
||||
|
@ -113,6 +115,7 @@ enum {
|
|||
Video_Mode_Rotate_XY,
|
||||
Video_Mode_Scale,
|
||||
Video_Mode_Clip,
|
||||
Video_Mode_Vector_Clip,
|
||||
Video_Mode_Realtime,
|
||||
|
||||
Video_Tracker_Menu,
|
||||
|
|
|
@ -73,6 +73,7 @@
|
|||
#include "visual_tool_rotatexy.h"
|
||||
#include "visual_tool_scale.h"
|
||||
#include "visual_tool_clip.h"
|
||||
#include "visual_tool_vector_clip.h"
|
||||
#include "visual_tool_drag.h"
|
||||
|
||||
|
||||
|
@ -106,7 +107,7 @@ END_EVENT_TABLE()
|
|||
|
||||
//////////////
|
||||
// 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
|
||||
|
@ -185,18 +186,20 @@ void VideoDisplay::Render() {
|
|||
wxASSERT(pw > 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
|
||||
dx1 = 0;
|
||||
dy1 = 0;
|
||||
dx2 = w;
|
||||
dy2 = h;
|
||||
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
|
||||
float thisAr = float(w)/float(h);
|
||||
float vidAr;
|
||||
|
@ -482,7 +485,8 @@ void VideoDisplay::OnKey(wxKeyEvent &event) {
|
|||
if (event.GetKeyCode() == 'D') SetVisualMode(2);
|
||||
if (event.GetKeyCode() == 'F') SetVisualMode(3);
|
||||
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 4: visual = new VisualToolScale(this); break;
|
||||
case 5: visual = new VisualToolClip(this); break;
|
||||
case 6: visual = new VisualToolVectorClip(this); break;
|
||||
default: visual = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,7 +46,7 @@ VisualDraggableFeature::VisualDraggableFeature() {
|
|||
type = DRAG_NONE;
|
||||
x = -1;
|
||||
y = -1;
|
||||
value = 0;
|
||||
value = value2 = 0;
|
||||
layer = 0;
|
||||
lineN = -1;
|
||||
line = NULL;
|
||||
|
@ -80,6 +80,12 @@ bool VisualDraggableFeature::IsMouseOver(int mx,int my) {
|
|||
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
|
||||
else if (type == DRAG_SMALL_CIRCLE) {
|
||||
int dx = mx-x;
|
||||
|
@ -120,6 +126,11 @@ void VisualDraggableFeature::Draw(OpenGLWrapper *gl) {
|
|||
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
|
||||
else if (type == DRAG_SMALL_CIRCLE) {
|
||||
gl->DrawCircle(x,y,4);
|
||||
|
|
|
@ -66,7 +66,7 @@ public:
|
|||
DraggableFeatureType type;
|
||||
int x,y;
|
||||
int layer; // Higher = above
|
||||
int value;
|
||||
int value,value2;
|
||||
|
||||
AssDialogue *line;
|
||||
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
|
||||
void VisualTool::SetOverride(wxString tag,wxString value) {
|
||||
|
|
|
@ -101,6 +101,7 @@ protected:
|
|||
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 FillPositionData();
|
||||
void SetOverride(wxString tag,wxString value);
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ void VisualToolClip::Draw() {
|
|||
|
||||
// Draw outside area
|
||||
SetLineColour(colour[3],0.0f);
|
||||
SetFillColour(colour[3],0.3f);
|
||||
SetFillColour(wxColour(0,0,0),0.5f);
|
||||
DrawRectangle(0,0,sw,dy1);
|
||||
DrawRectangle(0,dy2,sw,sh);
|
||||
DrawRectangle(0,dy1,dx1,dy2);
|
||||
|
|
|
@ -185,12 +185,7 @@ void VisualToolDrag::Draw() {
|
|||
// Draw dashed line
|
||||
else {
|
||||
SetLineColour(colour[3],0.5f,2);
|
||||
int steps = (dist-20)/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));
|
||||
}
|
||||
DrawDashedLine(x1,y1,x2,y2,6);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
204
aegisub/visual_tool_vector_clip.cpp
Normal file
204
aegisub/visual_tool_vector_clip.cpp
Normal file
|
@ -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();
|
||||
}
|
||||
}
|
64
aegisub/visual_tool_vector_clip.h
Normal file
64
aegisub/visual_tool_vector_clip.h
Normal file
|
@ -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…
Add table
Reference in a new issue